Отключение перетаскивания jQuery при прокрутке содержимого перетаскиваемого элемента - PullRequest
7 голосов
/ 26 января 2012

Обычно я не задаю такой вопрос / ответ, но решил, что сделаю это, так как я видел этот вопрос более 20 раз, и ни один ответ на самом деле не работает.Короче говоря, проблема в том, что если у вас есть прокручиваемый контент (overflow: auto; где-нибудь внутри перетаскиваемого элемента jQuery), когда вы щелкаете и перетаскиваете полосу прокрутки, которую перетаскивает родительский перетаскиваемый контейнер..

Вот пример некоторого html-кода, который представляет эту проблему:

<div class="draggable" style="width:100px;height:100px;">
  <div id="content" style="width:80px;height:80px;overflow:auto;">
    Nullam quis risus eget urna mollis ornare vel eu leo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nullam id dolor id nibh ultricies vehicula ut id elit.
  </div>
</div>

Типичный способ инициализации элемента для перетаскивания, выглядит примерно так:

$(".draggable").draggable()

Ответы [ 4 ]

6 голосов
/ 17 октября 2012

Я предлагаю решение, основанное на сочетании [1] и решения, предоставленного PriorityMark.Это решение работает более надежно, и я думаю, что оно немного более эффективно.

$(".draggable").draggable({
    start: function(event) {
        var content = $(this).children('.content');

        // if we're scrolling, don't start and cancel drag
        if (event.originalEvent.pageX-content.offset().left > content.innerWidth())
        {
            console.log('should-cancel');
            $(this).trigger("mouseup");
            return false;
        }
    }
});

Чтобы это работало, я немного скорректировал пример DOM (но это не должно быть такой большой проблемой):

<div class="draggable" style="width:100px;height:100px;overflow:auto;">
  <div class="content" style="width:80px;height:80px;">
    Nullam quis risus eget urna mollis ornare vel eu leo. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Nullam id dolor id nibh ultricies vehicula ut id elit.
  </div>
</div>​

Обратите внимание, что здесь перетаскиваемый div имеет переполнение , а не content div.Для решения это не имеет большого значения, но я не хотел добавлять дополнительный уровень div, так как не обязательно указывать это.

Вот jsfiddle .

[1] - прослушивать события мыши… кроме переполнения div: полоса прокрутки?

5 голосов
/ 26 января 2012

Решение состоит в том, чтобы привязать событие прокрутки к элементам, которые вы инициализируете, и к любому из этих дочерних элементов. Затем, когда любой из дочерних элементов вызовет команду прокрутки, найдите все перетаскиваемые родительские элементы этого элемента и установите прокручиваемый элемент данных для этого элемента.

В текущей версии пользовательского интерфейса jQuery (1.8.16) событие start всегда запускается при наведении курсора мыши на полосу прокрутки и перемещается вверх по дереву, поэтому в моем тестировании это решение работает очень хорошо.

$(".draggable").draggable({
    start: function() {
        // if we're scrolling, don't start and cancel drag
        if ($(this).data("scrolled")) {
            $(this).data("scrolled", false).trigger("mouseup");
            return false;
        }
    }
}).find("*").andSelf().scroll(function() {               
    // bind to the scroll event on current elements, and all children.
    //  we have to bind to all of them, because scroll doesn't propagate.

    //set a scrolled data variable for any parents that are draggable, so they don't drag on scroll.
    $(this).parents(".ui-draggable").data("scrolled", true);

});

Для вашего удовольствия от просмотра и удовольствия я также включил jsfiddle номера.

1 голос
/ 02 декабря 2014

Я искал эту проблему и нашел меньшее решение, которое идеально подходит для меня, и я хочу поделиться им. Мое решение состоит в том, чтобы прекратить распространять событие «mousedown» на child / content. Нет mousedown означает не перетаскивать;)

$(".draggable").draggable();
$("#content").mousedown(function(event) {
    event.stopPropagation();
});
0 голосов
/ 23 декабря 2014

Это симпатичное решение, но в нем есть одна ошибка.Как только он установлен на прокрутку, для перетаскивания элемента требуется второе перетаскивание.

...