【问题标题】:Event propagation, overlay and drag-and-drop events事件传播、覆盖和拖放事件
【发布时间】:2012-01-21 05:59:12
【问题描述】:

当用户将文件拖到窗口上时,我想在视口上覆盖一个 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>

【问题讨论】:

    标签: javascript jquery css html javascript-events


    【解决方案1】:

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

    例子:

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

    【讨论】:

    • 这就是办法!
    • 谢谢老兄,优雅简单的解决方案。 :)
    • 不幸的是,这对我不起作用,因为我在叠加层下方有输入,用户在不将项目拖到上面时需要能够与之交互。
    【解决方案2】:

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

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

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

    【讨论】:

    • 太棒了,这正是我想解决几个小时的问题;)但据我所知 jquery,$('*:visible').live() 一定很漂亮昂贵的选择器。可能有另一种解决方案吗?我的意思是 imgur.com 的人显然找到了一种方法(将文件从您的 finder/explorer 拖到网站上,您会看到),但我无法对代码进行逆向工程以了解他们是如何做到的:(跨度>
    • 我认为这也是一个相当繁琐的解决方案,但它是我找到的最简单的解决方案(工作项目有时间限制等等)。我也尝试过查看 imgur 代码,这不是我想深入研究的内容。
    【解决方案3】:
        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);
        }
    

    【讨论】:

    • 您能解释一下您的答案吗?未经详细说明发布代码可能会使其他人遇到同样的问题。
    • 这肯定需要澄清一下。
    • 我使用此代码在鼠标进入窗口拖动文件时显示拖放区。该对象有一个包含 event.timeStamp 的属性 .eTimestamp 并且我正在检查两个事件之间是否至少有 300 毫秒以防止多次触发(我遇到了这个问题)
    【解决方案4】:

    简单的解决方案是使用 dragover

    而不是使用 dragenter

    拖拉机 发生拖动时,当鼠标移到元素上时会触发此事件。很多时候,在监听器期间发生的操作将与 dragenter 事件相同。

    【讨论】:

    • 除非你检测不到它什么时候离开了drop zone。
    • 这也会导致代码更改覆盖层的可见性以重复触发,这可能(或可能不会)影响性能。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-02
    • 2011-05-25
    • 2020-05-10
    • 2010-11-13
    • 2011-08-26
    相关资源
    最近更新 更多