我试图重现GMail处理html5拖放附件的方式——只要你把文件拖过页面,它就会显示一个新的元素供你拖放它们。我把那部分写出来了(它不像我想象的那么直接)。
现在我试着通过改变鼠标光标来优化它,当鼠标在除drop元素以外的任何其他元素上时,告诉用户这里不允许drop。我想我可以用自定义光标来做到这一点,但这似乎不是GMail正在做的。规范建议也可以改变鼠标光标,但我似乎不能让它正常工作,使用dropzone/effectalallowed .
任何帮助将不胜感激,这是我目前的设置: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 + '">nne.dataTransfer.types is ' + e.dataTransfer.types + 'nne.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 + '">nne.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>
在源代码中进行了一些挖掘,发现您应该在dragover
事件处理程序中设置event.dataTransfer.dropEffect = 'move';
。谷歌dropEffect阅读更多,发现:
dataTransfer.dropEffect
控制用户在dragenter和过程中得到的反馈dragover事件。当用户将鼠标悬停在目标元素上时浏览器的游标将指示将要执行的操作类型放置(如复制、移动等)。这种影响可以发生在其中一个取值:none、copy、link、move
从:http://www.html5rocks.com/en/tutorials/dnd/basics/
编辑:这是我最后的结果:http://jsfiddle.net/guYWx/16/
必须做一个额外的技巧让它完美地工作。这样当你选择文本并在页面上拖动时,拖放器就不会出现了:
if ($.inArray('Files', e.dataTransfer.types) > -1)
@Langdon -谢谢您指出我所需要的东西!我给它点赞了。
在花了那么多时间之后,我让那个建议完全按预期工作了。
我使用 effectalallowed 结合dropEffect在执行拖放操作时提供视觉提示。完全跨浏览器!
$(document).on('dragstart dragenter dragover', function(event) {
// Only file drag-n-drops allowed, http://jsfiddle.net/guYWx/16/
if ($.inArray('Files', event.originalEvent.dataTransfer.types) > -1) {
// Needed to allow effectAllowed, dropEffect to take effect
event.stopPropagation();
// Needed to allow effectAllowed, dropEffect to take effect
event.preventDefault();
$('.dropzone').addClass('dropzone-hilight').show(); // Hilight the drop zone
dropZoneVisible= true;
// http://www.html5rocks.com/en/tutorials/dnd/basics/
// http://api.jquery.com/category/events/event-object/
event.originalEvent.dataTransfer.effectAllowed= 'none';
event.originalEvent.dataTransfer.dropEffect= 'none';
// .dropzone .message
if($(event.target).hasClass('dropzone') || $(event.target).hasClass('message')) {
event.originalEvent.dataTransfer.effectAllowed= 'copyMove';
event.originalEvent.dataTransfer.dropEffect= 'move';
}
}
}).on('drop dragleave dragend', function (event) {
dropZoneVisible= false;
clearTimeout(dropZoneTimer);
dropZoneTimer= setTimeout( function(){
if( !dropZoneVisible ) {
$('.dropzone').hide().removeClass('dropzone-hilight');
}
}, dropZoneHideDelay); // dropZoneHideDelay= 70, but anything above 50 is better
});
你必须改变cursor
的CSS属性。
您可以在这里找到cursor
不同值的列表。
您还可以使用cursor: url('foo.png');
指定自定义光标图像。