悬停子元素时触发 HTML5 dragleave

我遇到的问题是当悬停该元素的子元素时会触发该元素的 dragleave 事件.另外,dragenter 在再次悬停父元素时不会触发.

The problem I'm having is that the dragleave event of an element is fired when hovering a child element of that element. Also, dragenter is not fired when hovering back the parent element again.

我做了一个简化的小提琴:http://jsfiddle.net/pimvdb/HU6Mk/1/.

I made a simplified fiddle: http://jsfiddle.net/pimvdb/HU6Mk/1/.

HTML:

<div id="drag" draggable="true">drag me</div>

<hr>

<div id="drop">
    drop here
    <p>child</p>
    parent
</div>

使用以下 JavaScript:

with the following JavaScript:

$('#drop').bind({
                 dragenter: function() {
                     $(this).addClass('red');
                 },

                 dragleave: function() {
                     $(this).removeClass('red');
                 }
                });

$('#drag').bind({
                 dragstart: function(e) {
                     e.allowedEffect = "copy";
                     e.setData("text/plain", "test");
                 }
                });

它应该做的是在拖动某些东西时通过将 div 放置为红色来通知用户.这可行,但如果您拖入 p 子项,则 dragleave 会被触发,并且 div 不再是红色的.回到 drop div 也不会让它再次变红.需要完全移出drop div并再次拖回它以使其变为红色.

What it is supposed to do is notifying the user by making the drop div red when dragging something there. This works, but if you drag into the p child, the dragleave is fired and the div isn't red anymore. Moving back to the drop div also doesn't make it red again. It's necessary to move completely out of the drop div and drag back into it again to make it red.

是否可以防止 dragleave 在拖入子元素时触发?

Is it possible to prevent dragleave from firing when dragging into a child element?

2017 年更新: TL;DR,查找 CSS pointer-events: none;,如下面@HD 的回答中所述,适用于现代浏览器和 IE11.

2017 Update: TL;DR, Look up CSS pointer-events: none; as described in @H.D.'s answer below that works in modern browsers and IE11.

推荐答案

你只需要保留一个引用计数器,当你得到一个 dragenter 时增加它,当你得到一个 dragleave 时减少它.当计数器为 0 时 - 删除该类.

You just need to keep a reference counter, increment it when you get a dragenter, decrement when you get a dragleave. When the counter is at 0 - remove the class.

var counter = 0;

$('#drop').bind({
    dragenter: function(ev) {
        ev.preventDefault(); // needed for IE
        counter++;
        $(this).addClass('red');
    },

    dragleave: function() {
        counter--;
        if (counter === 0) { 
            $(this).removeClass('red');
        }
    }
});

注意:在 drop 事件中,将计数器重置为零,并清除添加的类.

Note: In the drop event, reset counter to zero, and clear the added class.

你可以运行它这里

相关文章