如何区分文件或文件夹是否被拖动之前被拖放?

我试图检测文件夹或文件是否在dragoverdragenter事件中被拖动。

例如:

ondrop事件中,有一个名为MouseEvent的参数,它有一个名为dataTransfer的字段,其中列出的文件( .files )或项目( .items )取决于浏览器,我可以在Chrome和Firefox中阅读 。 然而,对于这些领域(文件和.items )而言,这些领域是空着的。 问题是我需要这些信息,而拖动,而不是下降

注:对于文件和文件夹event.dataTransfer.types[i] === "Files"true

背景研究

我发现以下答案部分适合我的问题:

WebKit和Chrome因此在调用getData时候有相当的限制。 你不能在dragstartdragover里面做。 我认为这是规范的错误。

但是,这个答案是从2012年开始的, 我无法find关于这个主题的实际更新信息 ,所以我正在寻找这方面的最新信息。

TL; DR你不能:(

如果你想知道为什么这个问题还没有得到公认的答案,你可以阅读由OP创build的这个元问题我的答案

文件drag在HTML5中

我在这个主题的许多文档中做了一些研究,并在不同的浏览器上对自己进行了testing,所以我决定总结一下我所知道的有关文件拖放的知识。

拖延

拖动文件时,可以使用一些侦听器,例如:

  • dragenter
  • dragover
  • dragend
  • dragleave

鉴于这些是drag事件, event.dataTransferfiles 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。

要检测文件是否是文件夹,您将要:

  1. 检查文件是否有type == "" ,因为文件夹没有types。
  2. 检查文件大小是否是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