我遇到的问题dragleave是当悬停该元素的子元素时会触发元素事件.此外,dragenter再次悬停父元素时不会触发.
我做了一个简化的小提琴: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>
Run Code Online (Sandbox Code Playgroud)
使用以下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");
}
});
Run Code Online (Sandbox Code Playgroud)
它应该做的是通过在div那里拖动东西时使滴红色来通知用户.这样做有效,但是如果你拖入p孩子,那dragleave就会被激发而且div不再是红色.回到跌落div也不会再次变红.有必要完全移出掉落div并再次拖回它以使其变红.
dragleave拖入子元素时是否可以防止触发?
2017更新: TL; DR,查看CSS pointer-events: none;,如下面@ HD的答案中所述,适用于现代浏览器和IE11.
在窗口外拖动时,Firefox无法正确触发dragleave事件:
https://bugzilla.mozilla.org/show_bug.cgi?id=665704
https://bugzilla.mozilla.org/show_bug.cgi?id=656164
我正在尝试为此开发一种解决方法(我知道这可能是因为Gmail正在这样做),但我能想出的唯一的东西似乎真的很乱.
知道何时拖出窗外的一种方法是等待dragover事件停止发射(因为dragover在拖放操作期间不断发射).这就是我这样做的方式:
var timeout;
function dragleaveFunctionality() {
// do stuff
}
function firefoxTimeoutHack() {
clearTimeout(timeout);
timeout = setTimeout(dragleaveFunctionality, 200);
}
$(document).on('dragover', firefoxTimeoutHack);
Run Code Online (Sandbox Code Playgroud)
此代码实际上是一次又一次地创建和清除超时.除非dragover事件停止触发,否则将无法达到200毫秒的超时.
虽然这有效,但我不喜欢为此目的使用超时的想法.感觉不对.这也意味着在"掉落区"造型消失之前会有一点滞后.
我的另一个想法是检测鼠标何时离开窗口,但在拖放操作期间,这样做的正常方法似乎不起作用.
有没有人有更好的方法这样做?
更新:
这是我正在使用的代码:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Drag and Drop Issue</title>
<script src="http://code.jquery.com/jquery.js"></script>
</head>
<body>
Open up the console and look at what number is reporting when dragging files in and out of the window. The number should always be 0 when leaving …Run Code Online (Sandbox Code Playgroud) 这就是我想要实现的目标:
页面上有多个dropzones.用户应该能够从他们的操作系统中拖动文件并将其放入dropzones.
Dropzones在拖动过程中会突出显示.有两种视觉上不同类型的突出显示:"目标"(例如,元素以虚线边框勾勒出轮廓)和"悬停"(例如,元素获得明亮的背景).
目标突出显示同时在所有下拉列表中应用/删除:
- 当用户在页面上拖动文件时,应使用目标突出显示突出显示所有下拉区域.
- 当用户在页面外拖动文件,或取消拖放操作或执行拖放操作时,应从所有下拉区域中删除目标突出显示.
悬停突出显示应仅适用于一个dropzone:
- 当用户在dropzone上拖动文件时,应使用悬停突出显示突出显示该dropzone.
- 当用户将文件拖放到该dropzone之外,或取消拖放操作或执行拖放时,应从dropzone中删除目标突出显示.
当用户在dropzone上删除文件时,该文件的名称应该出现在dropzone中.
当用户在dropzones外部的页面上删除文件时,应删除所有突出显示的区域,并且不会发生任何其他情况.具体而言,浏览器不应打开已删除的文件.
解决方案应尽可能优雅:不喜欢使用超时,计数
dragenter/dragleave事件和重新应用突出显示等脏兮兮的黑客行为dragover.该解决方案应该适用于主流浏览器的最新版本.
删除dropzone之外的文件会导致浏览器打开该文件.
解:
$(document).on('dragover drop', function (e) {
e.preventDefault();
});
Run Code Online (Sandbox Code Playgroud)将文件拖放到dropzone会生成一个drop事件,其目标等于dropzone的子级而不是dropzone本身.
解:
$dropzones.on( 'drop', function (event) {
/* ... */
// Find the dropzone responsible for the event
$targetDropzone = $(event.target).closest($dropzones);
/* ... */
});
Run Code Online (Sandbox Code Playgroud)将文件悬停在dropzone的子节点上会生成多个dragleave事件,使悬停突出显示立即消失(当鼠标光标离开dropzone时,应从dropzone删除悬停突出显示,因此它将绑定到dragleave事件).
解决方案:使用dragout事件代替dragleave.dragout是jquery.event.dragout插件提供的自定义事件.元素的孩子不会触发此事件.
无法检测拖动文件离开document或的时刻 …