Événement de propagation, de recouvrement et de glisser-déplacer des événements

Je souhaite superposer un div sur la fenêtre lorsque l'utilisateur entraîne un fichier sur la fenêtre.

Cependant, j'ai des problèmes avec la propagation de l'événement. Lorsque je définis la superposition à display: block il semble déclencher un événement de dragleave , puis un autre dragenter et un autre dragleave nouveau, de sorte qu'il est toujours dans un état après-dragleave. Bien sûr, j'appelle e.stopPropagation() et e.preventDefault() sur l'objet événement, mais cela ne semble pas faire la différence.

La sortie console.log () lorsque vous faites glisser quelque chose sur la fenêtre:

 dragenter dragenter dragleave dragenter dragleave 

Le css. #overlay est configuré pour l' display: none par défaut, mais montrera si le body a la classe de dragenter :

  body { position: absolute; height: auto; top: 0; left: 0; right: 0; bottom: 0; margin: 0; padding: 0; } #overlay { position: absolute; height: auto; width: auto; top: 0; left: 0; right: 0; bottom: 0; background: url(bg.png) repeat-x top right, url(bg.png) repeat-x bottom left, url(bg.png) repeat-y top right, url(bg.p ng) repeat-y bottom left; display: none; } body.dragenter #overlay { display: block; } 

Le javascript. Ajoutez la classe 'dragenter' sur dragenter et la supprime sur Dragleave:

 $(document).on('dragenter', function (e) { e.stopPropagation(); e.preventDefault(); console.log('dragenter'); $(document.body).addClass('dragenter'); }); $(document).on('dragleave', function (e) { e.stopPropagation(); e.preventDefault(); console.log('dragleave'; $(document.body).removeClass('dragenter'); }); 

Le html:

 <body> <div id="overlay">...</div> ... </body> 

Merci à Scottux, qui m'a conduit sur la bonne voie.

Seul le problème était qu'il couvrait également le reste de la page, de sorte qu'aucun des éléments ou des entrées ne pouvait être cliqué. J'ai dû cacher #dragOverlay par défaut avec " display: none " et l'afficher sur cet événement

 // Display an overlay when dragging a file over $('*:visible').live('dragenter', function(e) { e.stopPropagation(); $('body').addClass('drag-enter'); }); 

Votre superposition prend toute la taille du document, lorsque vous faites glisser, il remplit son espace et sa souris est effectivement retirée du corps et est maintenant sur la superposition. Cela déclenche une boucle de souris / souris. Pour atteindre ce que vous recherchez, vous pouvez lier l'événement à une superposition transparente avec un index Z élevé sur la superposition visible qui a un indice z inférieur. Cela permettrait de garder l'événement dans l'élément le plus élevé.

Exemple:

http://jsfiddle.net/scottux/z7yaB/

  var dropZone = function() { var self = this; this.eTimestamp = 0; this.showDropZone = function(e) { e.stopPropagation(); e.preventDefault(); if (self.eTimestamp + 300 < e.timeStamp) { $("#coverDropZone").show(); self.eTimestamp = e.timeStamp; } return false; } this.hideDropZone = function(e) { e.stopPropagation(); e.preventDefault(); if (self.eTimestamp + 300 < e.timeStamp) { $("#coverDropZone").hide(); self.eTimestamp = e.timeStamp; } return false; } this.showImage = function(e) { e.stopPropagation(); e.preventDefault(); console.log(e); return false; } document.addEventListener('dragenter', self.showDropZone, false); document.addEventListener('dragleave', self.hideDropZone, false); document.addEventListener('drop', self.showImage, false); } 

La solution simple est au lieu d'utiliser dragoer use dragover

Dragover Cet événement est déclenché lorsque la souris est déplacée sur un élément lorsqu'une traînée se produit. La plupart du temps, l'opération qui se produit pendant un auditeur sera la même que l'événement dragenter.