Ian*_*Ian 4 javascript jquery drag-and-drop
我正在尝试创建一个文件拖放处理程序(将文件拖到浏览器窗口中,用于上传).
出于某种原因,当我将拖放监听器绑定到$("body")而不是绑定到$("div")主体中时,事件连续多次触发,有时甚至不停止(看似循环).可能是什么导致了这个?
这是代码的精简版:http://jsfiddle.net/WxMwK/9/
var over = false;
$("body")
.on("dragover", function(e){
e.preventDefault();
if (! over) {
over = true;
$("ul").append($("<li/>").text("dragover"));
}
})
.on("dragleave", function(e){
e.preventDefault();
if (over) {
over = false;
$("ul").append($("<li/>").text("dragleave"));
}
})
.on("drop", function(e){
e.preventDefault();
if (over) {
over = false;
$("ul").append($("<li/>").text("drop"));
}
});
Run Code Online (Sandbox Code Playgroud)
要测试:将文件拖到橙色区域,您会看到事件连续多次触发.
Eev*_*vee 12
这个(大部分)是正确的.简单地说:当鼠标移动到放置目标内的元素边缘时,您将获得光标下的dropenter元素和前面光标下的元素.绝对任何后代都会发生这种情况.dropleave
您无法检查与之关联的元素dragleave,因为如果您将鼠标从放置目标移动到子元素上,您将为dropenter孩子获得一个,然后dropleave为目标获得一个!这有点荒谬,我根本不知道这是多么有用的设计.
这是我前段时间提出的一个基于jQuery的糟糕解决方案.
var $drop_target = $(document.body);
var within_enter = false;
$drop_target.bind('dragenter', function(evt) {
// Default behavior is to deny a drop, so this will allow it
evt.preventDefault();
within_enter = true;
setTimeout(function() { within_enter = false; }, 0);
// This is the part that makes the drop area light up
$(this).addClass('js-dropzone');
});
$drop_target.bind('dragover', function(evt) {
// Same as above
evt.preventDefault();
});
$drop_target.bind('dragleave', function(evt) {
if (! within_enter) {
// And this makes it un-light-up :)
$(this).removeClass('js-dropzone');
}
within_enter = false;
});
// Handle the actual drop effect
$drop_target.bind('drop', function(evt) {
// Be sure to reset your state down here
$(this).removeClass('js-dropzone');
within_enter = false;
evt.preventDefault();
do_whatever(evt.originalEvent.dataTransfer.files);
});
Run Code Online (Sandbox Code Playgroud)
诀窍依赖于两个事实:
dragenter和dragleave将排队等候目标元素- 的顺序.dragenter和dragleave排队在一起.所以这就是发生的事情.
dragenter下,我设置了一些共享变量来指示拖动运动还没有完成解析.setTimeout延迟为零来立即更改该变量.dragleave事件处理程序.dragleave看到它与dragenter同一目标元素上的a配对,则表示鼠标必须已从某个后代移动到其他后代.否则,鼠标实际上是离开目标元素.setTimeout最后在零秒后解析,在另一个事件发生之前设置回变量.我想不出更简单的方法.
| 归档时间: |
|
| 查看次数: |
3119 次 |
| 最近记录: |