web-dev-qa-db-fra.com

glisser-déposer jQuery à l'aide d'événements en direct

J'ai une application avec une longue liste qui change fréquemment et j'ai besoin que les éléments de cette liste soient glissables.

J'ai utilisé le plugin jQuery UI draggable, mais il est lent à ajouter à plus de 400 éléments de liste, et doit être rajouté chaque fois que de nouveaux éléments de liste sont ajoutés.

Quelqu'un connaît-il un plug-in similaire au plug-in glissable jQuery UI qui utilise les événements .live() de jQuery 1.3? Cela résoudrait les deux problèmes.

41
devongovett

La solution de Wojtek a parfaitement fonctionné pour moi. J'ai fini par le changer un peu pour le faire étendre jQuery ...

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

Maintenant, au lieu de l'appeler comme:

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

... utilisez simplement:

$(selector).liveDraggable({opts})
44
stldoug

Ceci est un exemple de code qui a parfaitement fonctionné pour moi

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

Vous pouvez faire fonctionner le wrapper comme ceci:

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

(J'utilise un prototype avec jQuery - c'est pourquoi j'ai placé jQuery () au lieu de $ ())

Et maintenant, au lieu de $ (selector) .draggable ({opts}), utilisez liveDraggable (selector, {opts})

10
wojtekk

Le code de Stldoug a fonctionné pour moi, mais il n'est pas nécessaire de continuer à vérifier les données .data ("init") de chaque événement de survol. En outre, il est préférable d'utiliser "mousemove", car "mouseover" n'est pas toujours déclenché si votre souris est déjà sur l'élément lorsque la fonction .live entre en action.

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

Voici comment vous l'utilisez:

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

L'astuce consiste à ajouter ": not (.ui-draggable)" à votre sélecteur. Puisque jQuery ajoutera automatiquement la classe "ui-draggable" à votre élément quand il deviendra draggable, la fonction .live ne le ciblera plus. En d'autres termes, il ne se déclenche qu'une seule fois, contrairement à l'autre solution qui se déclenche encore et encore lorsque vous déplacez des objets.

Idéalement, vous pouvez simplement délier le "mousemove", mais cela ne fonctionne pas avec .live, malheureusement.

7
john

Combiner les meilleures réponses de @john et @jasimmk:

En utilisant .live:

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

.live est cependant obsolète, mieux vaut utiliser .on:

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

Comme l'a expliqué @john, .ui-draggable est automatiquement ajouté aux méthodes glissables, donc en excluant cette classe avec le sélecteur, vous vous assurez que draggable () ne sera appelé qu'une seule fois sur chaque élément. Et en utilisant .on réduira la portée du sélecteur et améliorera les performances.

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

JSFiddle

1
yokesh ganesan

Un exemple:

Turc:

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

Anglais:

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

Remarque: Vous pouvez utiliser on() au lieu de live() ou delegate. La on() a de bonnes performances que les autres

1
user1725620

Une autre option consiste à mélanger le gestionnaire de survol avec une classe amovible, comme ceci:

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

C'est assez simple et résout certains des problèmes rencontrés par d'autres réponses avec la reliure à plusieurs reprises lorsque vous passez la souris.

0
Micah

An version mise à jour qui n'utilise pas live car elle est obsolète:

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

Une vieille question. Mais threedubmedia a un plugin de glisser-déposer avec un support en direct (à partir de la v 1.7 connu simplement comme "on"). http://threedubmedia.com/code/event/drop Je ne l'ai pas beaucoup utilisé, je ne peux donc pas rendre compte de ses performances, etc., mais cela semble raisonnable.

0
Danny C