41

我有一个应用程序的列表很长,经常更改,我需要该列表中的项目可以拖动。

我一直在使用 jQuery UI 可拖动插件,但是添加到 400 多个列表项时速度很慢,并且每次添加新列表项时都必须重新添加。

有谁知道一个类似于使用 jQuery 1.3.live()事件的 jQuery UI 可拖动插件的插件?这将解决这两个问题。

4

10 回答 10

45

Wojtek 的解决方案非常适合我。我最终对其进行了一些更改以使其扩展 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});

...just use:

$(selector).liveDraggable({opts})
于 2010-07-28T02:05:22.913 回答
21

This is a sample of code that perfectly worked for me

$('.gadgets-column').live('mouseover',function(){
    $(this).draggable();
});
于 2010-10-11T07:25:22.997 回答
10

您可以像这样制作包装器功能:

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() 而不是 $() 的原因)

现在代替 $(selector).draggable({opts}) 使用 liveDraggable(selector, {opts})

于 2010-04-13T21:21:02.280 回答
7

Stldoug's code worked for me, but there's no need to keep checking the element's .data("init") on every mouseover event. Also, it's better to use "mousemove", as "mouseover" doesn't always get triggered if your mouse is already over the element when the .live function kicks in.

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

Here's how you use it:

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

The trick is to add ":not(.ui-draggable)" to your selector. Since jQuery will automatically add the "ui-draggable" class to your element when it becomes draggable, the .live function will no longer target it. In other words, it only triggers once, unlike the other solution which triggers over and over as you move stuff around.

Ideally, you could just .unbind the "mousemove", but that doesn't work with .live, unfortunately.

于 2011-05-17T08:06:41.737 回答
4

Combining the best answers from @john and @jasimmk:

Using .live:

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

.live is deprecated though, better to use .on:

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

As @john explained, .ui-draggable is automatically added to draggable methods, so by excluding that class with the selector, you ensure that draggable() will only be called once on each element. And using .on will reduce the scope of the selector, improving performance.

于 2013-07-18T20:51:01.650 回答
1

An example:

Turkish:

<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' });
});

English:

<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' });
});

Note: You can use on() instead of live() or delegate. The on() has good performance than others

于 2012-10-08T00:44:03.270 回答
1
$("html divs to drag").appendTo("#layoutDiv").draggable(options);

JSFiddle

于 2013-12-04T12:20:51.827 回答
0

An old question. But threedubmedia has drag and drop plugin with live (as of v 1.7 known as simply "on") support. http://threedubmedia.com/code/event/drop Haven't used it to much so I can't account for it performance, etc. but looks reasonable.

于 2012-08-15T14:34:45.883 回答
0

Another option is to mix the mouseover handler with a removable class, like so:

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

It's fairly straightforward and resolves some of the issues that other answers have with re-binding over and over as you mouseover.

于 2014-10-29T20:20:52.643 回答
0

An updated version that does not use live as it is deprecated:

function liveDraggable(selector, options) {
    $(document).on('mouseover', selector, function () {
        if (!$(this).data("init")) {
            $(this).data("init", true);
            $(this).draggable(options);
        }
    });
}
于 2014-12-07T17:07:47.683 回答