Evénement drop de l’interface utilisateur jQuery du widget autoroutable se déclenchant deux fois

Tout d’abord, je sais que cette question a déjà été posée, à la fois sur ce site et sur d’autres, mais les réponses sont toutes nulles pour mon scénario (s’ils ne le sont pas tout à fait), et (au moins pour la question ici: événement jQuery UI drop des .sortable sur sortingable ), la suggestion est simplement d’éteindre complètement le .sortable , ce qui n’est certainement pas ce que je veux faire.

D’accord, j’ai cette requête (gardez à l’esprit si des options ou des identifiants HTML ont l’air ridicules, ceci est juste pour le test afin que je puisse essayer de le comprendre):

 $(function () { $("#sortable").sortable({ revert: true }); $("#draggable, #draggable2").draggable({ connectToSortable: "#sortable", helper: "clone", revert: "invalid" }); $("#sortable").droppable({ drop: function (event, ui) { alert("done been sortingggered."); } }); $("ul, li").disableSelection(); }); 

Et voici le balisage valide:

 
  • Drag me down
  • Drag this down, too
  • Drag this down, also
  • Drag this down, as well
  • Drag this down, too
  • Drag this down, too
  • Drag this down, too
  • Drag this down, click
  • Drag this down, clicky
  • Item 1
  • Item 2
  • Item 3
  • Item 4
  • Item 5

Je n’ai pas de divs sortable qui se chevauchent ou quoi que ce soit du genre, et je pense comprendre «pourquoi» cela se produit (parce que sortable obtient les propriétés draggables par défaut?), Je n’arrive tout simplement pas à faire quelque chose à ce sujet.

Le problème, bien sûr, est que le …

 drop: function (event, ui) { alert("done been sortingggered."); } 

… est déclenché deux fois, quand ce n’est nécessaire qu’une fois.

Je penserais qu’il y aurait une solution simple à ce problème, car si ce problème nécessitait un tas de scripts complexes à résoudre, je penserais que ces widgets JQuery ne mériteraient pas tous les ennuis. Peut-être que je suis juste confus?

C’est un problème connu qui utilise à la fois les éléments sortable et droppable sur le même élément.

Vous pouvez utiliser à la place l’événement sortable du sortable .

jsFiddle Demo

 $("#sortable").sortable({ revert: true, receive: function (event, ui) { alert("receive been sortingggered."); } }).droppable({ }); 

J’avais un problème similaire. Il y avait 2 éléments largables, l’un d’eux avait une position relative et un autre, l’absolu. Ils n’étaient pas nesteds, mais une partie de celle ayant une position absolue était supérieure à celle de celle ayant une position relative (dans la documentation jQuery, cela s’appelle “intersection”). Lorsque j’ai déplacé un élément déplaçable vers la suppression “absolue”, l’événement de repository a été déclenché deux fois. Je cherchais depuis quelques jours, mais je n’ai trouvé aucune solution.

Ensuite, j’ai décidé de faire une solution de contournement générale simple. Ne semble pas très attrayant, mais cela aidera dans n’importe quelle situation avec le tir de 2 événements de largage.

 drop: function( e, ui ) { if ( ! $('.already-dropped').length ) { $('body').addClass('already-dropped'); setTimeout( function() { $('.already-dropped').removeClass('already-dropped'); }, 100 ); // callback code... } } 

Peut-être que je suis un peu en retard, mais j’ai posté ceci, espérons-le, cela aidera quelqu’un. C’est le code que j’utilise. Fondamentalement, si la fonction est appelée deux fois, l’intervalle entre elles doit être rapide (plus rapide que ce que les humains font habituellement), aussi je règle le nombre à 200 millisecondes.

J’ai utilisé localStorage pour définir une variable appelée “last_call”. C’est l’heure à laquelle la fonction a été appelée. Lors du prochain appel, nous vérifierons si la fonction a déjà été appelée. Si elle n’a pas été appelée, la fonction continuera à s’exécuter. S’il a été appelé, nous vérifierons quand il a été appelé pour la dernière fois. S’il a été appelé dans un délai de 200 millisecondes (appel de la machine évidemment, pas appel humain), nous ne l’appellerons plus.

  var d = new Date(); var this_time = d.getTime(); if ( localStorage.getItem("last_call") != null) { if ((this_time - parseInt(localStorage.getItem("last_call"))) < 100) { return; } } localStorage.setItem("last_call", this_time);