如何判断我是否有一个 File 对象列表?
How can I tell if I have a list of File objects?
我现在正在处理一些拖放操作,作为规范化步骤,我想检查我拥有的对象列表是否实际上是 File
s。看来我通常从 event.dataTransfer
得到的是 FileList
/ DataTransferFileList
,但我正在编写的函数最终可能会接受来自非事件源的 File 对象。所以,我正在考虑检查其中的各个项目是否是 File
或 DataTransferItem
.
的实例
然而,似乎我实际上可以从 JS 中得到的东西到处都是。 MDN tells me that DataTransfer.files
contains a FileList
; Chrome Devtools shows it as a DataTransferItemList
(in the console). An item within the list should be a 'File', according to MDN,但 Devtools 将其显示为 DataTransferItem
。奇怪的是,DataTransferItem
在 Devtools 控制台中未定义,并且肯定不适用于 instanceof
调用。不过,File
、FileList
和 DataTransferItemList
都在那里。
我什至还没有开始研究其他浏览器....
所以,我的问题分为两部分:
这些变化是怎么回事? MDN 是否更喜欢 Gecko 的功能而不是对 W3C 规范的解释?我是否在 Devtools 控制台中看到 Webkit 数据类型,但这些数据类型不一定转换为我可以用于 instanceof
?
的 JS 中可访问的任何内容(即 JS 构造函数)
鉴于所有这些变化,我如何判断某物是否是文件列表?我应该依赖一些鸭子打字解决方案而不是 instanceof
吗?
所以我得到了这样的结果:
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
s 和 File
s 周围添加了一个额外的层 [= =14=] 属性 个 drag/drop 个事件。
我现在正在处理一些拖放操作,作为规范化步骤,我想检查我拥有的对象列表是否实际上是 File
s。看来我通常从 event.dataTransfer
得到的是 FileList
/ DataTransferFileList
,但我正在编写的函数最终可能会接受来自非事件源的 File 对象。所以,我正在考虑检查其中的各个项目是否是 File
或 DataTransferItem
.
然而,似乎我实际上可以从 JS 中得到的东西到处都是。 MDN tells me that DataTransfer.files
contains a FileList
; Chrome Devtools shows it as a DataTransferItemList
(in the console). An item within the list should be a 'File', according to MDN,但 Devtools 将其显示为 DataTransferItem
。奇怪的是,DataTransferItem
在 Devtools 控制台中未定义,并且肯定不适用于 instanceof
调用。不过,File
、FileList
和 DataTransferItemList
都在那里。
我什至还没有开始研究其他浏览器....
所以,我的问题分为两部分:
这些变化是怎么回事? MDN 是否更喜欢 Gecko 的功能而不是对 W3C 规范的解释?我是否在 Devtools 控制台中看到 Webkit 数据类型,但这些数据类型不一定转换为我可以用于
instanceof
? 的 JS 中可访问的任何内容(即 JS 构造函数)
鉴于所有这些变化,我如何判断某物是否是文件列表?我应该依赖一些鸭子打字解决方案而不是
instanceof
吗?
所以我得到了这样的结果:
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
s 和 File
s 周围添加了一个额外的层 [= =14=] 属性 个 drag/drop 个事件。