我刚刚完成了一项功能,用户可以将文件拖到浏览器中,然后使用支持的文件上传插件来处理丢弃。
但是,为了向用户提供他们甚至可以放弃事物的提示,我已经实施了一个dragover
事件,以显示div
类似于“Drop Here”的内容”。反过来,这会隐藏具有“选择文件...”按钮的div
,并替换它,直到用户停止拖动。
但是,当我实现这一点时,拖动目标区域会导致闪烁。要明确:
div
显示“选择文件”界面。此外:
(警告:小提琴很粗糙。)
只需选择一些文字并将其拖到蓝色框上,您就会看到会发生什么;很明显它不应该表现出来的行为。
var $dropTarget = $("#container");
$(document).bind("dragover", function(e) {
if ($dropTarget.hasClass("highlight"))
return;
$dropTarget.addClass("highlight");
$dropTarget.find("[name='drop']").show();
$dropTarget.find("[name='drag']").hide();
}).bind("dragleave drop", function(e) {
if (!$dropTarget.hasClass("highlight"))
return;
$dropTarget.removeClass("highlight");
$dropTarget.find("[name='drop']").hide();
$dropTarget.find("[name='drag']").show();
});
说实话,我不知道该尝试什么。关于dragover
或dragleave
的行为没有大量文档,我甚至不知道为什么会这样,所以我甚至无法开始调试它。我觉得dragover
应该只发射一次,但即使在屏幕上拖动也只是一遍又一遍地发射它。
我看过谷歌图片和谷歌联系人的拖放行为,但他们的代码完全缩小并且不可读,我甚至找不到任何指定的“拖动”行为。
那么,对这种看似奇怪的行为有什么解决方法吗?如果这是WebKit中的一个错误,我怀疑,是否有一些很好的解决方法和/或黑客我可以使用?
感谢大家的时间!
答案 0 :(得分:18)
经过一个多小时的淘洗,我找到了someone who had a similar type of issue。似乎Chrome和Safari(至少5)在进入子元素时触发dragleave
(并且看似在对该元素进行任何更改时,包括显示/隐藏的子项)。
解决方法是检查pageX
中的pageY
和0
是否等于dragleave
(但不是 drop
)
var $dropTarget = $("#container");
$(document).bind("dragenter", function(e) {
if (e.target == this) {
return;
}
$dropTarget.addClass("highlight");
$dropTarget.find("[name='drop']").show();
$dropTarget.find("[name='drag']").hide();
}).bind("dragleave", function(e) {
if (e.originalEvent.pageX != 0 || e.originalEvent.pageY != 0) {
return false;
}
// Could use .trigger("drop") here.
$dropTarget.removeClass("highlight");
$dropTarget.find("[name='drop']").hide();
$dropTarget.find("[name='drag']").show();
}).bind("drop", function(e) {
$dropTarget.removeClass("highlight");
$dropTarget.find("[name='drop']").hide();
$dropTarget.find("[name='drag']").show();
});
答案 1 :(得分:0)
我有一些使用拖放文件的项目,在我的项目中也发现了同样的问题, 这是针对您的问题的解决方案,并已针对您的情况进行了测试,那就是100%工作
这是魔术代码:
<style type="text/css">
.drag * {
pointer-events: none;
}
</style>
<div class="drag" id='container'>
<div name='drop' style='display: none;'>DROP HERE</div>
<div name='drag'>DRAG HERE</div>
</div>
答案 2 :(得分:-1)
我发现使用Eric的解决方案,如果我在使用此解决方案后将Win10谷歌浏览器的屏幕拖到另一个窗口上,它对我来说并不起作用。将条件更改为AND工作。
var $dropTarget = $("#container");
$(document).bind("dragenter", function(e) {
if (e.target == this) {
return;
}
$dropTarget.addClass("highlight");
$dropTarget.find("[name='drop']").show();
$dropTarget.find("[name='drag']").hide();
}).bind("dragleave", function(e) {
if (e.originalEvent.pageX != 0 || e.originalEvent.pageY != 0) {
return false;
}
// Could use .trigger("drop") here.
$dropTarget.removeClass("highlight");
$dropTarget.find("[name='drop']").hide();
$dropTarget.find("[name='drag']").show();
}).bind("drop", function(e) {
$dropTarget.removeClass("highlight");
$dropTarget.find("[name='drop']").hide();
$dropTarget.find("[name='drag']").show();
});