如何判断我是否有File对象列表?

时间:2015-04-15 19:17:51

标签: javascript file file-upload drag-and-drop

我现在正在处理一些拖放操作,并且作为规范化步骤,我想检查我拥有的对象列表实际上是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调用。不过,FileListDataTransferItemListinstanceof都在那里。

我还没有开始进入其他浏览器......

所以,我的问题有两个部分:

  1. 这些变化是什么? MDN是否偏爱Gecko功能而不是对W3C规范的解释?我是否在Devtools控制台中看到了Webkit数据类型,但是这些数据类型并不一定转换为JS中的任何可访问的(即JS构造函数),我可以使用instanceof

  2. 在给出所有这些变化的情况下,如何判断某些内容是否为文件列表?我应该依靠一些鸭子打字解决方案而不是{{1}}吗?

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的浏览器,并且会在FileListFile的{​​{1}}属性中添加一个额外的层。拖放事件。