Pregunta

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

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

¿Alguien sabe de un complemento similar al complemento que se puede arrastrar de la interfaz de usuario de jQuery que utiliza los eventos .live () de jQuery 1.3? Esto resolvería ambos problemas.

¿Fue útil?

Solución

La solución de Wojtek funcionó perfectamente para mí. Terminé cambiándolo un poco para hacer 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})

Otros consejos

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

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

Podrías hacer que el envoltorio funcione de esta manera:

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

(Yo uso prototipo con jQuery, por eso coloqué 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 revisando los datos .data (" init ") del elemento en cada evento de mouseover. Además, es mejor usar " mousemove " ;, como " 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 usas:

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

El truco es agregar ": no (.ui-draggable) " a su selector. Dado que jQuery agregará automáticamente el " ui-draggable " asigne una clase a su elemento cuando se pueda arrastrar, la función .live ya no lo enfocará. 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 mueves cosas.

Lo ideal es que, simplemente, no puedas vincular el " mousemove " ;, pero eso no funciona con .live, por desgracia.

Combinando las mejores respuestas de @john y @jasimmk:

Utilizando .live:

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

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

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

Como se explica en @john, .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 una vez a draggable () en cada elemento. Y el uso de .on reducirá el alcance del selector, mejorando el rendimiento.

Un ejemplo:

Turco:

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

inglés:

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

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

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

JSFiddle

Una vieja pregunta. Pero threedubmedia tiene un complemento de arrastrar y soltar con soporte en vivo (a partir de la versión 1.7 conocido simplemente como " on "). http://threedubmedia.com/code/event/drop No lo he usado mucho, así que no puedo explicar su rendimiento, etc. pero parece razonable.

Otra opción es mezclar el controlador de mouseover con una clase extraíble, de este modo:

$('.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 otras respuestas tienen al volver a enlazar una y otra vez cuando pasas el mouseover.

Una versión actualizada que no usa 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);
        }
    });
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top