@millwright

В чём причина ошибки mousemove при повторном mousedown?

Пытаюсь сделать скроллер для карусели на jQuery без дополнительных плагинов или библиотек. При повторном mousedown, mousemove срабатывает 1-3 раза, курсор меняется на "not-allowed", и больше ничего не происходит. Если отпустить кнопку мыши, курсор меняется на обычный, а mouseup не срабатывает.
$(document).ready(function () {
                var drag = false;
                var brick = $(".brick");
                var brickPos = 0;

                $(brick).mousedown(function (event) {
                    console.log("DOWN");
                    drag = true;
                    var offset = event.pageX;
                    var target = $(this).parent().siblings(".product-carousel-container");
                    $(document).mousemove(function (e) {
                        if (drag) {
                            var relX = e.pageX - offset + brickPos;
                            var move = -relX * 8 / 3;
                            console.log(relX);
                            $(brick).css("left", relX);
                            $(target).css("left", move);
                            if (relX <= 0) {
                                $(brick).css("left", 0);
                                $(target).css("left", 0);
                            }
                            if (relX >= 785) {
                                $(brick).css("left", 790);
                                $(target).css("left", -790 * 8 / 3);
                            }
                        }
                    });
                });


                $(document).mouseup(function () {
                    console.log("UP");
                    $(document).off("mousemove");
                    drag = false;
                    brickPos = parseInt($(brick).css("left"));
                });

            });

Не относящиеся к вопросу замечания по коду приветствуются.
  • Вопрос задан
  • 804 просмотра
Решения вопроса 1
@millwright Автор вопроса
Помогло отключение выделения текста через CSS user-select.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 2
alexey-m-ukolov
@alexey-m-ukolov Куратор тега JavaScript
Без конкретного примера на jsfiddle сложно понять, что не так, но главное подозрение падает на установку mousemove внутри другого обработчика. На первый взгляд, всё должно работать, но по симптомам проблема именно здесь. Да и в принципе это ненужное усложнение, спокойно можно обойтись без него.

По поводу замечаний по коду - у вас довольно много ошибок начинающего: весь код одной лапшой, полно магических цифр, названия переменных неинформативные, никакой инкапсуляции. Например, я так и не смог понять, каким элементом карусели является brick - это карточка, кнопка листания, что-то ещё?

В первом приближении должно быть что-то похожее на это:
spoiler
var carousel = (function() {
  var isInsideCarousel = false,
    brickPos = 0,
    magicNumbers = {
      first: 8, // Количество элементов в ряду?
      second: 3, // Количество рядов?
      third: 5, // Какой-то padding родительского контейнера?
      fourth: 790, // Ширина контейнера?
      fifth: 0, // Левая граница страницы?
    },
    $brick, offset, target;

  function turnOn(e) {
    console.log("DOWN");
    isInsideCarousel = true;
    offset = e.pageX;
    target = $(this).parent().siblings(".product-carousel-container");
  }

  function turnOff() {
    console.log("UP");
    isInsideCarousel = false;
    brickPos = parseInt($(brick).css("left"), 10);
  }

  function scroll(e) {
    var relX, move;

    if (!isInsideCarousel) {
      return;
    }

    relX = e.pageX - offset + brickPos;
    move = -relX * magicNumbers.first / magicNumbers.second;

    console.log(relX);

    $(brick).css("left", relX);
    $(target).css("left", move);

    if (relX <= magicNumbers.fifth) {
      $(brick).css("left", magicNumbers.fifth);
      $(target).css("left", magicNumbers.fifth);
    } else if (relX >= magicNumbers.fourth - magicNumbers.third) {
      $(brick).css("left", magicNumbers.fourth);
      $(target).css("left", -1 * magicNumbers.fourth * magicNumbers.first / magicNumbers.second);
    }
  }

  return function($el) {
    $brick = $el;
    $el.mousedown(turnOn);
    $(document).mousemove(scroll);
    $(document).mouseup(turnOff);
  }
}());

$(document).ready(function() {
  carousel($(".brick"));
});


Бонусным уровнем было бы обернуть это всё в jquery-плагин, но я не стал этого делать.
Ответ написан
bogdanov-s
@bogdanov-s
Че-то там программирую
mousemove и mouseup вешайте на brick, такжн нужно подписаться на mouseout и по собьітию делать тоже что и по mouseup.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы