我正在尝试检测是否在 dragover
或 dragenter
事件中拖动了文件夹或文件。
在ondrop
事件中,有一个名为MouseEvent
的参数,其中包含一个名为dataTransfer
的字段,其中列出了文件(.files
)或项目({{ 1}}),取决于浏览器,我可以在Chrome和Firefox中阅读。但是,对于.items
和dragover
个事件,这些字段(dragenter
和.files
)为空。问题是拖动时我需要这些信息,而不是丢弃。
注意:对于文件和文件夹.items
均为event.dataTransfer.types[i] === "Files"
。
我发现the following answer部分适合我的问题:
WebKit,以及Chrome,对于何时可以致电
true
非常严格。您不允许在getData
或dragstart
内执行此操作。我认为这是规范的错误。
但是答案是从2012年开始,我无法找到有关该主题的实际更新信息,因此我正在寻找有关此问题的最新信息。
答案 0 :(得分:88)
TL; DR你不能:(
如果您想知道为什么这个问题仍然没有得到接受的答案,您可以阅读OP创建的this meta question ,和{{3 }} 强>
drag
/ drop
我在这个主题的许多文档中做了一些研究,并在各种浏览器上自己测试了,所以我决定总结一下我所知道的关于文件拖放的所有内容。
拖动文件时,您可以使用一些侦听器,例如:
dragenter
dragover
dragend
dragleave
鉴于这些是drag
个事件,files
的{{1}}属性将为event.dataTransfer
或为空(length == 0
)。
想象一下,您可以在拖动事件中读取文件:即使用户不想将文件上传到您的网站,您也可以阅读所有内容。认真对待它是没有意义的。想象一下,您正在将文件从桌面拖到另一个文件夹,并且您不小心将其拖动到网页中:现在网页会读取您的文件并将您的个人信息存储在其服务器上...... 这将是一个巨大的安全漏洞强>
但是,您仍然可以通过迭代数组null
来检测用户是否正在拖动文件(以及文件我也指文件夹,因为文件夹是文件)。您可以创建一个函数来检查拖动事件是否包含文件,然后在事件处理程序中调用它。
示例:
event.dataTransfer.types
当您将文件放入drop 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
}
}
(或您使用dropzone的任何元素)时,您将使用事件<div>
的侦听器来读取某些文件属性,例如name,大小,类型和最后修改日期。
要检测文件是否是文件夹,您将:
drop
,因为文件夹没有类型。type == ""
,因为文件夹的大小倍数为4096字节(即4KiB)。示例:
size%4096 == 0
已知问题:由于该文件夹实际上是文件,因此这是将它们与其他类型文件区分开来的唯一方法。虽然此方法无法确定文件是否为文件夹:它可能是没有扩展名且大小为0或N x 4096B的文件。
以下是一些工作示例,以了解我上面所说的内容并自行测试。在运行它们之前,请确保您的浏览器my answer。玩得开心:
答案 1 :(得分:0)
这是关于Dropping -on drop事件的工作 - (请注意,这不适用于dragover事件):
if matchingEmployee:
print 'Employee(s) found'
for o in matchingEmployee:
o.food = b
在FF V49,Chrome V55,Edge V25上测试
答案 2 :(得分:0)
您可以使用 FileReader 或 webkitGetAsEntry()
从文件夹中分离文件ie11不支持webkitGetAsEntry(),因此请记住这一点!
代码如下:
onDrop(event) {
let files = event.dataTransfer ? event.dataTransfer.files : 'null';
for(let i = 0, file; file = files[i]; i++) {
var reader = new FileReader();
reader.onload = function (e) {
console.log('it is a file!');
};
reader.onerror = function (e) {
console.log('it is a folder!');
};
reader.readAsText(file);
}
}
答案 3 :(得分:0)
我能够在页面上获取整个被拖拉的东西的整个Mimetype。 Mimetype对于文件夹似乎是空白的,因此也许您可以通过这种方式区分它。
部分代码(摘自React):
function handleDragOver(ev: DragEvent) {
ev.preventDefault();
ev.dataTransfer!.dropEffect = 'copy';
console.log(Array.from(ev.dataTransfer.items).map(i => [i.kind,i.type].join('|')).join(', '));
}
document.addEventListener('dragover',handleDragOver);
输出如下:
file|image/x-icon, file|image/jpeg, file|application/vnd.ms-excel
当我在页面上拖动3个文件时。
不确定它是否只能在localhost上运行,我还没有在任何地方上传此文件,但是它完全可以正常工作。