如何区分文件或文件夹是否被拖动之前被拖放?
我试图检测文件夹或文件是否在dragover
或dragenter
事件中被拖动。
例如:
在ondrop
事件中,有一个名为MouseEvent
的参数,它有一个名为dataTransfer
的字段,其中列出的文件( .files
)或项目( .items
)取决于浏览器,我可以在Chrome和Firefox中阅读 。 然而,对于这些领域(文件和.items
)而言,这些领域是空着的。 问题是我需要这些信息,而拖动,而不是下降 。
注:对于文件和文件夹event.dataTransfer.types[i] === "Files"
为true
。
背景研究
我发现以下答案部分适合我的问题:
WebKit和Chrome因此在调用
getData
时候有相当的限制。 你不能在dragstart
或dragover
里面做。 我认为这是规范的错误。
但是,这个答案是从2012年开始的, 我无法find关于这个主题的实际更新信息 ,所以我正在寻找这方面的最新信息。
TL; DR你不能:(
如果你想知道为什么这个问题还没有得到公认的答案,你可以阅读由OP创build的这个元问题 , 我的答案 。
文件drag
在HTML5中
我在这个主题的许多文档中做了一些研究,并在不同的浏览器上对自己进行了testing,所以我决定总结一下我所知道的有关文件拖放的知识。
拖延
拖动文件时,可以使用一些侦听器,例如:
-
dragenter
-
dragover
-
dragend
-
dragleave
鉴于这些是drag
事件, event.dataTransfer
的files
event.dataTransfer
将具有length == 0
或为空( null
)。
您无法在拖动事件中读取文件详细信息, 也无法检查它们是否是文件夹。 这不是一个错误,这是一个安全措施。
想象一下,您可以通过拖放事件来阅读文件:即使用户不想将file upload到您的网站,也可以阅读所有内容。 这是没有道理的,认真的。 想象一下,你是从桌面拖动一个文件到另一个文件夹,然后不小心将其拖到一个网页上:现在网页读取你的文件并将你的个人信息存储在它的服务器上…… 这将是一个巨大的安全缺陷。
不过,您仍然可以通过遍历数组event.dataTransfer.types
来检测用户是否正在拖动文件(也是文件夹,也就是文件夹是文件)。 您可以创build一个函数来检查拖动事件是否包含文件,然后在事件处理程序中调用它。
例:
function containsFiles(event) { if (event.dataTransfer.types) { for (var i=0; i<event.dataTransfer.types.length; i++) { if (event.dataTransfer.types[i] == "Files") { return true; } } } return false; } function handleDragEnter(e) { e.preventDefault(); if (containsFiles(e)) { // The drag event contains files // Do something } else { // The drag event doesn't contain files // Do something else } }
删除
当你将一个文件拖放到放置<div>
(或者你用作dropzone的任何元素)时,你将使用一个事件drop
的监听器来读取一些文件属性,如名称,大小,types和最后修改date。
要检测文件是否是文件夹,您将要:
- 检查文件是否有
type == ""
,因为文件夹没有types。 - 检查文件大小是否是4096的倍数:
size%4096 == 0
,因为文件夹总是有4096字节(4KiB)的倍数。
例:
function handleDrop(e) { e.stopPropagation(); e.preventDefault(); var files = e.dataTransfer.files; for (var i = 0, f; f = files[i]; i++) { // iterate in the files dropped if (!f.type && f.size%4096 == 0) { // The file is a folder // Do something } else { // The file is not a folder // Do something else } } }
已知问题:由于该文件夹实际上是文件,这是将它们与另一种文件区分开的唯一方法。 虽然这种方法并不能绝对保证文件是一个文件夹:它可能是一个没有扩展名的文件,大小为0或者正好是N×4096B。
工作示例
这里有一些工作的例子,看看我在上面所说的行动和自己testing。 在运行之前,请确保您的浏览器支持拖放function 。 玩的开心:
- 文件放置显示信息 (由我制作)
- 文件/文件夹识别 (由我做的)
- 文件拖动检测 (从CSS技巧)
这是关于Dropping – drop事件的工作(请注意,这不适用于dragover事件):
isDraggedItemIsFile = function(e) { // handle FF if (e.originalEvent.dataTransfer.files.length == 0) { return false; } // handle Chrome if (e.originalEvent.dataTransfer.items) { if (typeof (e.originalEvent.dataTransfer.items[0].webkitGetAsEntry) == "function") { return e.originalEvent.dataTransfer.items[0].webkitGetAsEntry().isFile; } else if (typeof (e.originalEvent.dataTransfer.items[0].getAsEntry) == "function") { return e.originalEvent.dataTransfer.items[0].getAsEntry().isFile; } } return true; }; $forms.on('drop', function(e) { if (isDraggedItemIsFile(e)) { // do something if file } else{ // is directory } });
testingFF V49,Chrome V55,Edge V25