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

时间:2012-01-21 05:59:13

标签: javascript jquery css html5 javascript-events

当用户将文件拖到窗口上时,我想在视口上叠加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:

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

4 个答案:

答案 0 :(得分:6)

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

示例:

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

答案 1 :(得分:1)

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

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

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

答案 2 :(得分:1)

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

答案 3 :(得分:0)

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

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