jQuery Drag and Drop с использованием живых событий - PullRequest
41 голосов
/ 26 ноября 2009

У меня есть приложение с длинным списком, который часто меняется, и мне нужно, чтобы элементы этого списка были перетаскиваемыми.

Я использовал перетаскиваемый плагин jQuery UI, но добавить его к 400+ элементам списка медленно, и его нужно добавлять заново каждый раз, когда добавляются новые элементы списка.

Кто-нибудь знает плагин, похожий на перетаскиваемый плагин jQuery UI, который использует события .live() jQuery 1.3? Это решило бы обе проблемы.

Ответы [ 10 ]

44 голосов
/ 28 июля 2010

Решение Войтека отлично сработало для меня. Я немного изменил его, чтобы расширить JQuery ...

(function ($) {
   $.fn.liveDraggable = function (opts) {
      this.live("mouseover", function() {
         if (!$(this).data("init")) {
            $(this).data("init", true).draggable(opts);
         }
      });
      return this;
   };
}(jQuery));

Теперь вместо того, чтобы называть это как:

$(selector).draggable({opts});

... просто используйте:

$(selector).liveDraggable({opts})
21 голосов
/ 11 октября 2010

Это пример кода, который отлично сработал для меня

$('.gadgets-column').live('mouseover',function(){
    $(this).draggable();
});
10 голосов
/ 14 апреля 2010

Вы можете сделать функцию-обёртку такой:

function liveDraggable(selector, options){
  jQuery(selector).live("mouseover",function(){
    if (!jQuery(this).data("init")) {
      jQuery(this).data("init", true);
      jQuery(this).draggable(options);
    }
  });
}

(я использую прототип с jQuery - поэтому я поместил jQuery () вместо $ ())

И теперь вместо $ (селектор) .draggable ({opts}) используйте liveDraggable (селектор, {opts})

7 голосов
/ 17 мая 2011

Код Stldoug работал для меня, но нет необходимости постоянно проверять элемент .data ("init") для каждого события наведения мыши. Кроме того, лучше использовать «mousemove», так как «mouseover» не всегда срабатывает, если ваша мышь уже находится над элементом, когда включается функция .live.

(function ($) {
    $.fn.liveDraggable = function (opts) {
        this.live("mousemove", function() {
            $(this).draggable(opts);
        });
    };
}(jQuery));

Вот как вы его используете:

$('.thing:not(.ui-draggable)').liveDraggable();

Хитрость заключается в том, чтобы добавить ": not (.ui-draggable)" к вашему селектору. Поскольку jQuery автоматически добавит класс «ui-draggable» к вашему элементу, когда он станет перетаскиваемым, функция .live больше не будет нацеливаться на него. Другими словами, он срабатывает только один раз, в отличие от другого решения, которое срабатывает снова и снова, когда вы перемещаете вещи.

В идеале вы могли бы просто .unbind "mousemove", но это не работает с .live, к сожалению.

4 голосов
/ 19 июля 2013

Объединение лучших ответов от @john и @jasimmk:

Использование .live:

$('li:not(.ui-draggable)').live('mouseover',function(){
    $(this).draggable(); // Only called once per li
});

.live устарел, хотя лучше использовать .on:

$('ul').on('mouseover', 'li:not(.ui-draggable)', function(){
    $(this).draggable();  // Only called once per li
});

Как объяснил @john, .ui-draggable автоматически добавляется в перетаскиваемые методы, поэтому, исключая этот класс с помощью селектора, вы гарантируете, что draggable () будет вызываться только один раз для каждого элемента. А использование .on уменьшит область действия селектора, улучшив производительность.

1 голос
/ 04 декабря 2013
$("html divs to drag").appendTo("#layoutDiv").draggable(options);

JSFiddle

1 голос
/ 08 октября 2012

Пример:

Турецкий:

<div id="diyalogKutusu">
    <div id="diyalog-baslik">..baslik..</div>
    <div id="icerik">..icerik..</div>
</div>

$(document).on("mouseover", "#diyalogKutusu", function() {
    $(this).draggable({ handle: '#diyalog-baslik' });
});

английский

<div id="dialogBox">
    <div id="dialogBox-title">..title..</div>
    <div id="content">..content..</div>
</div>

$(document).on("mouseover", "#dialogBox", function() {
    $(this).draggable({ handle: '#dialogBox-title' });
});

Примечание. Вы можете использовать on() вместо live() или delegate. on() имеет хорошую производительность, чем другие

0 голосов
/ 07 декабря 2014

Обновленная версия , которая не использует live , поскольку она устарела:

function liveDraggable(selector, options) {
    $(document).on('mouseover', selector, function () {
        if (!$(this).data("init")) {
            $(this).data("init", true);
            $(this).draggable(options);
        }
    });
}
0 голосов
/ 29 октября 2014

Другой вариант - смешать обработчик наведения мыши со сменным классом, например так:

$('.outer-container').on('mouseover', '.my-draggable.drag-unbound', function(e) {
  $(this).draggable().removeClass('drag-unbound');
});

Это довольно просто и решает некоторые проблемы, которые возникают у других ответов с повторным связыванием при наведении курсора мыши.

0 голосов
/ 15 августа 2012

старый вопрос. Но у threedubmedia есть плагин drag-and-drop с поддержкой в ​​реальном времени (начиная с версии 1.7, которая называется просто «on») http://threedubmedia.com/code/event/drop Я не очень много использовал его, поэтому я не могу объяснить его производительность и т. Д., Но выглядит разумно.

...