事件传播,叠加和拖放事件
当用户将文件拖到窗口上时,我想在视口上叠加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的透明叠加层。 这将使事件保持在最高元素中。
例:
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事件相同。