我试图检测是否在 dragover 或 dragenter 事件中拖动了文件夹或文件 .
例如:
在 ondrop
事件中,有一个名为 MouseEvent
的参数,其中有一个名为 dataTransfer
的字段,其中列出了文件( .files
)或项目( .items
),具体取决于浏览器,我可以在Chrome和Firefox中读取它 . 但是,对于 dragover
和 dragenter
事件,这些字段( .files
和 .items
)为空 . 问题是 I need that information while dragging, not dropping .
注意:对于文件和文件夹, event.dataTransfer.types[i] === "Files"
是 true
.
背景研究
我发现the following answer部分适合我的问题:
WebKit,以及Chrome,对于何时可以调用getData非常严格 . 你不允许在dragstart或dragover中执行此操作 . 我认为这是规范的错误 .
但答案是2012年和 I can't find actual updated information on the topic ,所以我正在寻找有关此问题的最新信息 .
4 回答
TL; DR你不能:(
如果您想知道为什么这个问题仍未得到接受的答案,您可以阅读OP创建的这个元问题,以及我的答案 .
HTML5中的文件拖放
我在这个主题的许多文档中做了一些研究,并在各种浏览器上自己测试了,所以我决定总结一下我所知道的关于文件拖放的所有知识 .
拖动
拖动文件时可以使用一些侦听器,例如:
dragenter
dragover
dragend
dragleave
鉴于这些是
drag
事件,event.dataTransfer
的files
属性将具有length == 0
或为空(null
) .您无法在拖动事件中读取文件详细信息,也无法检查它们是否为文件夹 . 这不是一个错误,它是一种安全措施 .
想象一下,您可以在拖动事件中读取文件:即使用户不想将文件上传到您的站点,您也可以阅读所有内容 . 认真对待它是没有意义的 . 想象一下,您正在将文件从桌面拖到另一个文件夹,并且不小心将其拖动到网页中:现在网页会读取您的文件并将您的个人信息存储在其服务器上... that would be a huge security flaw.
但是,您仍然可以通过迭代数组
event.dataTransfer.types
来检测用户是否正在拖动文件(以及文件我也指文件夹,因为文件夹是文件) . 您可以创建一个函数来检查拖动事件是否包含文件,然后在事件处理程序中调用它 .例:
掉线
当您将文件放入drop
<div>
(或您使用dropzone的任何元素)时,您将使用事件drop
的侦听器来读取某些文件属性,例如名称,大小,类型和上次修改日期 .要检测文件是否是文件夹,您将:
检查文件是否有
type == ""
,因为文件夹没有类型 .检查文件大小是否为4096的倍数:
size%4096 == 0
,因为文件夹的大小倍数为4096字节(即4KiB) .例:
KNOWN ISSUE: 由于这些文件夹实际上是文件,因此这是将它们与另一种文件区分开来的唯一方法 . 虽然此方法无法确定文件是文件夹:它可能是没有扩展名且大小为0或N x 4096B的文件 .
工作实例
以下是一些工作示例,以了解我上面所说的内容并自行测试 . 在运行它们之前,请确保您的浏览器supports drag and drop features . 玩得开心:
File drop display info(由我制作)
File/folder recognize(由我制作)
File drag detect(来自css-tricks)
这是关于Dropping -on drop事件的工作 - (请注意,这不适用于dragover事件):
在FF V49,Chrome V55,Edge V25上测试
您可以使用 FileReader 或 webkitGetAsEntry() 将文件与文件夹分开
ie11不支持webkitGetAsEntry(),所以请记住这一点!
代码如下所示:
我能够将整个Mimetype的东西拖到我的页面上 . 对于文件夹,Mimetype似乎是空白的,所以也许你可以通过这种方式区分它 .
部分代码(从React中提取):
输出如下:
当我在页面上拖动3个文件时 .
不确定它是否仅适用于localhost,我还没有在任何地方上传,但它完全正常工作 .
MDN docs on DataTransferItem