English 中文(简体)
jQuery Drag And Drop Using Live Events
原标题:

I have an application with a long list that changes frequently, and I need the items of that list to be draggable.

I ve been using the jQuery UI draggable plugin, but it is slow to add to 400+ list items, and has to be re-added every time new list items are added.

Does anyone know of a plugin similar to the jQuery UI draggable plugin that uses jQuery 1.3 s .live() events? This would solve both problems.

最佳回答

Wojtek s solution worked perfectly for me. I wound up changing it a tad bit to make it extend jQuery...

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

Now instead of calling it like:

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

...just use:

$(selector).liveDraggable({opts})
问题回答

This is a sample of code that perfectly worked for me

$( .gadgets-column ).live( mouseover ,function(){
    $(this).draggable();
});

You could make wrapper function like this:

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

(I use prototype with jQuery - that s why i placed jQuery() instead of $())

And now instead of $(selector).draggable({opts}) use liveDraggable(selector, {opts})

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.

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.

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

$("html divs to drag").appendTo("#layoutDiv").draggable(options);

JSFiddle

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.

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.

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




相关问题
getGridParam is not a function

The HTML: <a href="javascript:void(0)" id="m1">Get Selected id s</a> The Function: jQuery("#m1").click( function() { var s; s = jQuery("#list4").getGridParam( selarrrow )...

selected text in iframe

How to get a selected text inside a iframe. I my page i m having a iframe which is editable true. So how can i get the selected text in that iframe.

jQuery cycle page with links

I am using the cycle plugin with pager functionality like this : $j( #homebox ) .cycle({ fx: fade , speed: fast , timeout: 9000, pager: #home-thumbs , ...

jquery ui dialog opens only once

I have a button that opens a dialog when clicked. The dialog displays a div that was hidden After I close the dialog by clicking the X icon, the dialog can t be opened again.

jConfirm with this existing code

I need help to use jConfirm with this existing code (php & Jquery & jAlert). function logout() { if (confirm("Do you really want to logout?")) window.location.href = "logout.php"; } ...

Wrap text after particular symbol with jQuery

What I m trying to do, is wrap text into div inside ll tag. It wouldn t be a problem, but I need to wrap text that appears particularly after "-" (minus) including "minus" itself. This is my html: &...

热门标签