jQuery Arrastrar y soltar usando Live Events

Tengo una aplicación con una larga lista que cambia con frecuencia, y necesito que los elementos de esa lista sean arrastrables.

He estado usando el complemento jQuery UI draggable, pero es lento para agregar a más de 400 elementos de la lista, y tiene que volver a agregarse cada vez que se agreguen nuevos elementos de la lista.

¿Alguien sabe de un complemento similar al plugin jQuery UI que se puede arrastrar y que usa los eventos .live() jQuery 1.3? Esto resolvería ambos problemas.

La solución de Wojtek funcionó perfectamente para mí. Terminé cambiándolo un poco para que se extienda jQuery …

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

Ahora en lugar de llamarlo así:

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

…Solo usa:

 $(selector).liveDraggable({opts}) 

Esta es una muestra de código que funcionó perfectamente para mí

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

Puedes hacer que el wrapper funcione así:

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

(Utilizo el prototipo con jQuery – por eso puse jQuery () en lugar de $ ())

Y ahora, en lugar de $ (selector) .draggable ({opts}) usa liveDraggable (selector, {opts})

El código de Stldoug funcionó para mí, pero no hay necesidad de seguir comprobando los datos del elemento (“init”) en cada evento mouseover. Además, es mejor usar “mousemove”, ya que “mouseover” no siempre se activa si el mouse ya está sobre el elemento cuando se activa la función .live.

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

Así es como lo usa:

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

El truco es agregar “: no (.ui-draggable)” a su selector. Dado que jQuery agregará automáticamente la clase “ui-draggable” a su elemento cuando se vuelva arrastrable, la función .live ya no se dirigirá a él. En otras palabras, solo se dispara una vez, a diferencia de la otra solución que se dispara una y otra vez a medida que mueve cosas.

Idealmente, podría simplemente desconectar el “mousemove”, pero eso no funciona con .live, desafortunadamente.

Combinando las mejores respuestas de @john y @jasimmk:

Usando .live :

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

.live está en desuso, mejor usar .on :

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

Como @john explicó, .ui-draggable se agrega automáticamente a los métodos que se pueden arrastrar, por lo que al excluir esa clase con el selector, se asegura de que solo se llame a draggable () una vez en cada elemento. Y usar .on reducirá el scope del selector, mejorando el rendimiento.

Un ejemplo:

Turco:

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

Inglés:

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

Nota: Puede usar on() lugar de live() o delegate . El on() tiene un buen rendimiento que otros

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

JSFiddle

Una vieja pregunta. Pero threedubmedia tiene un plugin de arrastrar y soltar con soporte en vivo (a partir del v 1.7 conocido simplemente como “on”). http://threedubmedia.com/code/event/drop No lo he usado demasiado, así que no puedo explicar su rendimiento, etc. pero parece razonable.

Otra opción es mezclar el manejador de mouseover con una clase extraíble, así:

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

Es bastante sencillo y resuelve algunos de los problemas que tienen otras respuestas al volver a vincular una y otra vez a medida que pasa el mouseover.

Una versión actualizada que no utiliza en vivo ya que está en desuso:

 function liveDraggable(selector, options) { $(document).on('mouseover', selector, function () { if (!$(this).data("init")) { $(this).data("init", true); $(this).draggable(options); } }); }