事件传播,叠加和拖放事件

当用户将文件拖到窗口上时,我想在视口上叠加div。

但是,我在事件传播方面遇到了麻烦。 当我将叠加设置为display: block它似乎触发了一个dragleave事件,然后是另一个dragenter ,然后是另一个dragleave ,所以它总是处于后拖拉状态。 当然我在事件对象上调用e.stopPropagation()e.preventDefault() ,但它似乎没有什么区别。

在窗口上拖动某些内容时,console.log()输出:

 dragenter dragenter dragleave dragenter dragleave 

css。 #overlay默认设置为display: none ,但会显示body是否包含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; } 

这个javascript。 在dragenter上添加’dragenter’类并在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'); }); 

html:

  
...
...

感谢Scottux,这让我走上了正确的轨道。

唯一的问题是它还覆盖了页面的其余部分,因此没有任何元素或输入是可点击的。 我必须默认使用“ display:none ”隐藏#dragOverlay并在此事件中显示它

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

您的叠加占据整个文档大小,当您拖入时,它会填满其空间,鼠标会被有效地从身体中取出,现在位于叠加层上方。 这会触发mouseleave / mouseenter循环。 为了实现您的目标,您可能希望将事件绑定到具有较低z-index的可见叠加层上具有高z-index的透明叠加层。 这将使事件保持在最高元素中。

例:

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

简单的解决方案是使用dragenter使用dragover而不是使用dragenter

dragover当发生拖动时,鼠标在元素上移动时会触发此事件。 大多数情况下,在监听器期间发生的操作将与dragenter事件相同。