Pergunta

Eu tenho um aplicativo com uma longa lista que muda frequentemente, e eu preciso dos itens dessa lista a ser arrastado.

Estou usando o plugin jQuery UI arrastável, mas é lento para adicionar mais de 400 itens da lista, e tem de ser re-adicionado cada vez que novos itens da lista são adicionados.

Alguém sabe de um plugin similar ao jQuery UI arrastável plugin que usa eventos .live() jQuery 1.3 de? Isso resolveria dois problemas.

Foi útil?

Solução

A solução da Wojtek funcionou perfeitamente para mim. Acabei mudando-o um pouquinho para torná-lo estender jQuery ...

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

Agora, em vez de chamá-lo como:

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

... apenas use:

$(selector).liveDraggable({opts})

Outras dicas

Este é um exemplo de código que perfeitamente trabalhou para mim

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

Você poderia fazer função de mensagens publicitárias como esta:

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

(eu uso protótipo com jQuery - é por isso que eu coloquei jQuery () em vez de $ ())

E agora em vez de $ (selector) .draggable ({opta}) uso liveDraggable (selector, {opta})

código de Stldoug funcionou para mim, mas não há necessidade de manter a verificação .data do elemento ( "init") em cada evento mouseover. Além disso, é melhor usar "mousemove", como "mouseover" nem sempre se desencadeou se o seu mouse já está sobre o elemento quando a função .Live entra em ação.

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

Aqui está como você usá-lo:

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

O truque é adicionar ": não (.ui-draggable)" para o seu selector. Desde jQuery irá adicionar automaticamente a classe "ui-draggable" para o seu elemento quando ele se torna draggable, a função .Live deixarão de alvejá-lo. Em outras palavras, ele só dispara uma vez, ao contrário da outra solução que gatilhos mais e mais como você se move coisas ao redor.

Idealmente, você poderia simplesmente .unbind o "mousemove", mas isso não funciona com .Live, infelizmente.

Combinando as melhores respostas de @ John e @jasimmk:

Usando .live:

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

.live está obsoleta, porém, melhor para uso .on:

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

Como explicado @ John, .ui-draggable é automaticamente adicionado aos métodos que podem ser arrastadas, por isso, excluindo a classe com o seletor, você garante que draggable () só será chamado uma vez em cada elemento. E usando .on irá reduzir o escopo do seletor, melhorando o desempenho.

Um exemplo:

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: Você pode usar on() vez de live() ou delegate. O on() tem o bom desempenho do que outros

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

jsFiddle

Uma questão de idade. Mas threedubmedia tem de arrastar e soltar plugin com ao vivo (a partir de v 1.7 conhecido simplesmente como "on") de apoio. http://threedubmedia.com/code/event/drop Não usei-o para muito, então não posso explicá-lo desempenho, etc., mas parece razoável.

Outra opção é misturar o manipulador de mouseover com uma classe removível, assim:

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

É bastante simples e resolve alguns dos problemas que outras respostas têm com re-ligação mais e mais como você mouseover.

Um versão atualizada que não usa ao vivo , uma vez que está obsoleta:

function liveDraggable(selector, options) {
    $(document).on('mouseover', selector, function () {
        if (!$(this).data("init")) {
            $(this).data("init", true);
            $(this).draggable(options);
        }
    });
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top