Javascript 如何检测正在拖动的文件而不是页面上的可拖动元素?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/6848043/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I detect a file is being dragged rather than a draggable element on my page?
提问by aepheus
I'm using the html5 events to enable both file and element drag-and-drop. I've attached the dragover event to the body and am using event delegations to show where a draggable can be dropped. My question is how can I tell if a file is being dragged vs. an element with draggable=true. I know I can detect the element being dragged via e.target. But, how can I tell if it is a file.
我正在使用 html5 事件来启用文件和元素拖放。我已将 dragover 事件附加到正文,并使用事件委托来显示可以放置可拖动对象的位置。我的问题是如何判断一个文件是被拖动还是一个带有 draggable=true 的元素。我知道我可以检测到通过 e.target 拖动的元素。但是,我怎么知道它是否是一个文件。
jquery is available.
jQuery 可用。
Also, nottalking about jquery-ui draggable here.
另外,这里不讨论 jquery-ui 可拖动。
I'm starting to think maybe the only way to detect the file will be by exclusion and detecting the elements instead. If we're not dragging an element, assume it's a file. This will require extra work though as images and links are draggable by default, so I will have to add events to them or prevent them from dragging.
我开始认为检测文件的唯一方法可能是通过排除和检测元素来代替。如果我们不拖动一个元素,假设它是一个文件。这将需要额外的工作,因为默认情况下图像和链接是可拖动的,因此我必须向它们添加事件或阻止它们拖动。
回答by Bouke
You can detect what is being dragged by inspecting dataTransfer.types
. This behaviour is not (yet) consistent across browsers so you have to check for the existence of 'Files'
(Chrome) and 'application/x-moz-file'
(Firefox).
您可以通过检查来检测正在拖动的内容dataTransfer.types
。这种行为(尚未)在浏览器之间保持一致,因此您必须检查'Files'
(Chrome) 和'application/x-moz-file'
(Firefox)是否存在。
// Show the dropzone when dragging files (not folders or page
// elements). The dropzone is hidden after a timer to prevent
// flickering to occur as `dragleave` is fired constantly.
var dragTimer;
$(document).on('dragover', function(e) {
var dt = e.originalEvent.dataTransfer;
if (dt.types && (dt.types.indexOf ? dt.types.indexOf('Files') != -1 : dt.types.contains('Files'))) {
$("#dropzone").show();
window.clearTimeout(dragTimer);
}
});
$(document).on('dragleave', function(e) {
dragTimer = window.setTimeout(function() {
$("#dropzone").hide();
}, 25);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="dropzone" style="border: 2px dashed black; background: limegreen; padding: 25px; margin: 25px 0; display: none; position">
Drop files here!
</div>
hover files here
回答by elanoism
Further improvement of bouke's answer:
进一步改进 bouke 的回答:
Since chrome calls dragleave of document on every dragenter foe each element, it can cause flickering of the dropzone, especially if there are many nested elements.
由于 chrome 在每个元素上的每个 dragenter 上调用文档的 dragleave,它会导致 dropzone 闪烁,尤其是在有许多嵌套元素的情况下。
$(document).on('dragleave', function(e) {
dragTimer = window.setTimeout(function() {
$("#dropzone").hide();
}, 25);
});
What I did to fix the issue for me is increasing the timeout a bit and adding clearTimeout before setting each timeout, since previously in some cases there would be more than one timeouts which are not cleared in the dragover event, since dragTimer stores only the latest one. The result version:
我为解决这个问题所做的是稍微增加超时并在设置每个超时之前添加 clearTimeout ,因为以前在某些情况下会在拖动事件中没有清除多个超时,因为 dragTimer 只存储最新的一。结果版本:
$(document).on('dragleave', function(e) {
window.clearTimeout(dragTimer);
dragTimer = window.setTimeout(function() {
$("#dropzone").hide();
}, 85);
});
btw, thanks for the idea! My other solution was an absolute pain :)
顺便说一句,谢谢你的主意!我的另一个解决方案是绝对的痛苦:)
回答by Tomá? Zato - Reinstate Monica
I just use this to detect files in dragover
event:
我只是用它来检测dragover
事件中的文件:
Array.prototype.indexOf.call(files, "Files")!=-1 // true if files
回答by Shannon Matthews
Use the function below to check if the drag source is an external file.
使用以下函数检查拖动源是否为外部文件。
Tested on Windows 7 with:
- Firefox version 39
- Chrome version 44
- Safari version 5.1.7
在 Windows 7 上测试:
- 火狐版本 39
- 铬版本 44
- Safari 版本 5.1.7
function isDragSourceExternalFile(dataTransfer){
// Source detection for Safari v5.1.7 on Windows.
if (typeof Clipboard != 'undefined') {
if (dataTransfer.constructor == Clipboard) {
if (dataTransfer.files.length > 0)
return true;
else
return false;
}
}
// Source detection for Firefox on Windows.
if (typeof DOMStringList != 'undefined'){
var DragDataType = dataTransfer.types;
if (DragDataType.constructor == DOMStringList){
if (DragDataType.contains('Files'))
return true;
else
return false;
}
}
// Source detection for Chrome on Windows.
if (typeof Array != 'undefined'){
var DragDataType = dataTransfer.types;
if (DragDataType.constructor == Array){
if (DragDataType.indexOf('Files') != -1)
return true;
else
return false;
}
}
}
Example Usage with JQuery
JQuery 使用示例
$(document).on('dragover', function(e){
var IsFile = isDragSourceExternalFile(e.originalEvent.dataTransfer);
console.log(IsFile);
});