Dragend, dragenter et dragleave tirant immédiatement lorsque je traîne

J'essaie de faire une liste d'éléments qui peuvent être repositionnés en faisant glisser et déposer. Le premier élément, encadré 1, fonctionne parfaitement 100% du temps. Parfois, la deuxième boîte fonctionne, mais aucune d'entre elles ne fonctionne comme prévu. Ils semblent déclencher tous les événements de glissement à la fois dès que vous commencez à les traîner.

J'utilise le dernier Chrome (v23) si cela compte.

var $questionItems = $('.question-item'); $questionItems .on('dragstart', startDrag) .on('dragend', removeDropSpaces) .on('dragenter', toggleDropStyles) .on('dragleave', toggleDropStyles); function startDrag(){ console.log('dragging...'); addDropSpaces(); } function toggleDropStyles(){ $(this).toggleClass('drag-over'); console.log(this); } function addDropSpaces(){ $questionItems.after('<div class="empty-drop-target"></div>'); console.log('drop spaces added'); } function removeDropSpaces(){ $('.empty-drop-target').remove(); console.log('drop spaces removed'); } 

Voici le HTML:

 <div class="question-item" draggable="true">Box 1: Milk was a bad choice.</div> <div class="question-item" draggable="true">Box 2: I'm Ron Burgundy?</div> <div class="question-item" draggable="true">Box 3: You ate the entire wheel of cheese?</div> <div class="question-item" draggable="true">Box 4: Scotch scotch scotch</div> 

Voici un jsFiddle de mon code: http://jsfiddle.net/zGSpP/5/

A eu ce problème tout à l'heure – c'est un bug de Chrome, vous ne devez pas manipuler le DOM dans l'événement dragStart, sinon le fichier DragEnd se déclenche immédiatement. La solution pour moi s'est avérée être – utiliser setTimeout () et manipuler le DOM à l'intérieur de la fonction que vous avez expiré.

Je ne sais pas si c'est un bogue ou non, mais je pense que le problème survient lorsque vous modifiez le DOM dans le gestionnaire Dragstart. La raison pour laquelle la première boîte fonctionne, je présume, a quelque chose à voir avec le fait que sa position est antérieure aux autres boîtes du DOM et lorsque vous changez le DOM, la position (?) De la première n'est pas affectée et les événements Dragdrop Feu de manière fiable.

Vous devrez plutôt refacher votre code et ajouter les DropSpaces dans le gestionnaire d'événement dragenter. Vous devriez changer votre méthode addDropSpaces pour tenir compte du fait qu'il sera appelé plusieurs fois, cependant.

La vie est plus simple avec jQuery. C'est exactement ce que vous avez décrit que vous vouliez, en utilisant jQueryUI.

http://jqueryui.com/draggable/#sortable

Ce qui permet le tri. Le code:

 <!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <title>jQuery UI Draggable + Sortable</title> <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" /> <script src="http://code.jquery.com/jquery-1.8.3.js"></script> <script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script> <link rel="stylesheet" href="/resources/demos/style.css" /> <style> ul { list-style-type: none; margin: 0; padding: 0; margin-bottom: 10px; } li { margin: 5px; padding: 5px; width: 150px; } </style> <script> $(function() { $( "#sortable" ).sortable({ revert: true }); $( "#draggable" ).draggable({ connectToSortable: "#sortable", helper: "clone", revert: "invalid" }); $( "ul, li" ).disableSelection(); }); </script> </head> <body> <ul> <li id="draggable" class="ui-state-highlight">Drag me down</li> </ul> <ul id="sortable"> <li class="ui-state-default">Item 1</li> <li class="ui-state-default">Item 2</li> <li class="ui-state-default">Item 3</li> <li class="ui-state-default">Item 4</li> <li class="ui-state-default">Item 5</li> </ul> </body> </html> 

Voir aussi: http://jqueryui.com/sortable/

Essayez d'ajouter les événements manuellement, le long chemin, quelque chose comme:

 $questionItems[0].on('dragstart', startDrag); $questionItems[0].on('dragend', removeDropSpaces) $questionItems[0].on('dragenter', toggleDropStyles) $questionItems[0].on('dragleave', toggleDropStyles); $questionItems[1].on('dragstart', startDrag); $questionItems[1].on('dragend', removeDropSpaces) $questionItems[1].on('dragenter', toggleDropStyles) $questionItems[1].on('dragleave', toggleDropStyles); 

Etc. juste pour voir l'effet?