【发布时间】:2012-01-17 14:13:02
【问题描述】:
我正在尝试重现 GMail 处理 html5 拖放附件的方式——只要您将文件拖到页面上,它就会显示一个新元素供您放置它们。我解决了这部分问题(它并不像我想象的那么简单)。
现在我试图通过在鼠标悬停在除放置元素之外的任何其他元素上时更改鼠标光标来完善它,以告诉用户此处不允许放置。我想我可以使用自定义光标来完成,但这似乎不是 GMail 正在做的事情。 The spec 建议也可以更改鼠标光标,但我似乎无法使用 dropzone/effectAllowed 使其正常工作。
任何帮助将不胜感激,这是我当前的设置:http://jsfiddle.net/guYWx/1/
ETA:这是我最终得到的结果:http://jsfiddle.net/guYWx/16/
<body style="border: 1px solid black;">
<div id="d0" style="border: 1px solid black;">drag files onto this page</div>
<div id="d1" style="border: 1px solid black; display: none; background-color: red;">-> drop here <-</div>
<div id="d2" style="border: 1px solid black;">and stuff will happen</div>
<div style="float: left;">mouse them all over </div>
<div style="float: left;">these elements</div>
<br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/><br/>
<div>end page</div>
</body>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script type="text/javascript">
var resetTimer;
var reset = function()
{
$('#d1').hide();
};
var f = function(e)
{
var srcElement = e.srcElement? e.srcElement : e.target;
if ($.inArray('Files', e.dataTransfer.types) > -1)
{
e.stopPropagation();
e.preventDefault();
e.dataTransfer.dropEffect = (srcElement.id == 'd1') ? 'copy' : 'none';
if (e.type == "dragover")
{
if (resetTimer)
{
clearTimeout(resetTimer);
}
$('#d1').show();
console.info('dropped on <' + srcElement.tagName.toLowerCase() + ' id="' + srcElement.id + '">\n\ne.dataTransfer.types is ' + e.dataTransfer.types + '\n\ne.dataTransfer.files.length is ' + e.dataTransfer.files.length);
}
else if (e.type == "dragleave")
{
resetTimer = window.setTimeout(reset, 25);
}
else if (e.type == "drop")
{
reset();
alert('dropped on <' + srcElement.tagName.toLowerCase() + ' id="' + srcElement.id + '">\n\ne.dataTransfer.files.length is ' + (e.dataTransfer.files ? e.dataTransfer.files.length : 0));
}
}
};
document.body.addEventListener("dragleave", f, false);
document.body.addEventListener("dragover", f, false);
document.body.addEventListener("drop", f, false);
</script>
【问题讨论】:
-
嗨,我自己已经为此奋斗了好几个小时。你的代码比我的要好得多。你能解释一下重置超时延迟的目的吗?
-
它可以防止dragleave事件的误报。当您将 dragover/dragleave 绑定到具有一堆子元素的元素时,当您将鼠标从子元素移到子元素时,事件将触发。我用对
reset的调用替换了超时,所以当你拖过去时,你可以看到它有多糟糕:jsfiddle.net/guYWx/20(在 Chrome 中隐藏/显示很多)。
标签: html drag-and-drop