我现在正在处理一些拖放操作,并且作为规范化步骤,我想检查我拥有的对象列表实际上是File
。我通常从event.dataTransfer
获得的内容似乎是FileList
/ DataTransferFileList
,但我写的函数最终可能会接受来自非事件源的File对象。所以,我在考虑检查其中的单个项目是File
还是DataTransferItem
的实例。
然而,似乎我可以从JS中获得的东西到处都是。 DataTransfer.files
FileList
包含DataTransferItemList
的{{3}}; Chrome Devtools将其显示为DataTransferItem
(在控制台中)。列表中的项目应为'文件',MDN tells me,但Devtools会将其显示为DataTransferItem
。奇怪的是,instanceof
在Devtools控制台中未定义,并且肯定不适用于File
调用。不过,FileList
,DataTransferItemList
和instanceof
都在那里。
我还没有开始进入其他浏览器......
所以,我的问题有两个部分:
这些变化是什么? MDN是否偏爱Gecko功能而不是对W3C规范的解释?我是否在Devtools控制台中看到了Webkit数据类型,但是这些数据类型并不一定转换为JS中的任何可访问的(即JS构造函数),我可以使用instanceof
?
在给出所有这些变化的情况下,如何判断某些内容是否为文件列表?我应该依靠一些鸭子打字解决方案而不是{{1}}吗?
答案 0 :(得分:2)
所以我最终得到了类似的东西:
var knownFiles = [];
// If not already a list, make it a list
if (!files.length) {
files = [files];
}
// Iterate manually to accommodate Array, FileList, DataTransferItemList
for (i = 0; i < files.length; i++) {
file = files[i];
if (Blob && file instanceof Blob) {
// Safari, Firefox, IE land here
knownFiles.push(file);
} else if (file.webkitGetAsEntry) {
// Chrome wraps Files in DataTransferItems
knownFiles.push(file.webkitGetAsEntry());
}
}
return knownFiles;
其中大部分来自浏览器(Chrome 41,Safari 8,Firefox 36和IE 11),但我也从这里获得了一些帮助:https://code.flickr.net/2012/12/10/drag-n-drop/。
显然,Chrome是唯一困扰DataTransferItemList
interface的浏览器,并且会在FileList
和File
的{{1}}属性中添加一个额外的层。拖放事件。