拖动子元素时会触发父元素的“ dragleave”
回答:
我具有以下HTML结构,并且将dragenter
和dragleave
事件附加到了<div id="dropzone">
元素上。
<div id="dropzone"> <div id="dropzone-content">
<div id="drag-n-drop">
<div class="text">this is some text</div>
<div class="text">this is a container with text and images</div>
</div>
</div>
</div>
回答:
当我将文件拖到时<div id="dropzone">
,dragenter
事件将按预期触发。但是,当我将鼠标移到子元素(例如)上时<div
id="drag-n-drop">,会dragenter
为该<div id="drag-n-
drop">元素dragleave
触发该事件,然后为该<div id="dropzone">
元素触发该事件。
如果我<div
id="dropzone">再次将鼠标悬停在该元素上,dragenter
则再次触发该事件,这很酷,但是随后dragleave
为刚刚剩下的子元素触发了该事件,因此removeClass
执行了该指令,这并不酷。
此行为有问题的原因有两个:
我只附加
dragenter
&dragleave
,<div id="dropzone">
所以我不明白为什么子元素也要附加这些事件。我仍将鼠标悬停在
<div id="dropzone">
元素上,同时将其悬停在其子元素上,因此我不希望dragleave
开火!
回答:
回答:
所以…我该怎么做,以至于当我在<div
id="dropzone">元素上拖动文件时,dragleave
即使我在任何子元素上拖动也不会触发…仅当我离开该<div
id="dropzone">元素时才触发。在元素边界内的任何位置悬停/拖动都不 应该 触发dragleave
事件。
我至少在支持HTML5拖放的浏览器中需要跨浏览器兼容,因此此答案是不够的。
似乎Google和Dropbox已经解决了这一问题,但是它们的源代码是缩小的/复杂的,所以我无法从其实现中解决这一问题。
回答:
我终于找到了我满意的解决方案。我实际上找到了几种方法来做自己想做的事,但是没有一种方法能像当前解决方案一样成功。在一种解决方案中,由于在#dropzone
元素上添加/删除了边框,我经常出现闪烁现象。如果将鼠标悬停在浏览器之外,则不会删除它。
无论如何,我最好的hacky解决方案是这样的:
var dragging = 0;attachEvent(window, 'dragenter', function(event) {
dragging++;
$(dropzone).addClass('drag-n-drop-hover');
event.stopPropagation();
event.preventDefault();
return false;
});
attachEvent(window, 'dragover', function(event) {
$(dropzone).addClass('drag-n-drop-hover');
event.stopPropagation();
event.preventDefault();
return false;
});
attachEvent(window, 'dragleave', function(event) {
dragging--;
if (dragging === 0) {
$(dropzone).removeClass('drag-n-drop-hover');
}
event.stopPropagation();
event.preventDefault();
return false;
});
效果很好,但是Firefox中出现了问题,因为Firefox是双重调用的,dragenter
所以我的计数器关闭了。但是,这并不是一个非常优雅的解决方案。
然后我偶然发现了一个问题:在窗口外拖动时如何检测Firefox中的dragleave事件
因此,我接受了答案并将其应用于我的情况:
$.fn.dndhover = function(options) { return this.each(function() {
var self = $(this);
var collection = $();
self.on('dragenter', function(event) {
if (collection.size() === 0) {
self.trigger('dndHoverStart');
}
collection = collection.add(event.target);
});
self.on('dragleave', function(event) {
/*
* Firefox 3.6 fires the dragleave event on the previous element
* before firing dragenter on the next one so we introduce a delay
*/
setTimeout(function() {
collection = collection.not(event.target);
if (collection.size() === 0) {
self.trigger('dndHoverEnd');
}
}, 1);
});
});
};
$('#dropzone').dndhover().on({
'dndHoverStart': function(event) {
$('#dropzone').addClass('drag-n-drop-hover');
event.stopPropagation();
event.preventDefault();
return false;
},
'dndHoverEnd': function(event) {
$('#dropzone').removeClass('drag-n-drop-hover');
event.stopPropagation();
event.preventDefault();
return false;
}
});
这是干净优雅的,似乎可以在到目前为止我测试过的所有浏览器中使用(尚未测试IE)。
以上是 拖动子元素时会触发父元素的“ dragleave” 的全部内容, 来源链接: utcz.com/qa/434700.html