event.dataTransfer.files 是标准 FileList 对象,类数组、只读、支持 length 和索引访问,但无 forEach/map 等数组方法;遍历推荐 for 循环、扩展运算符(IE 不支持)或 Array.from;与 行为一致。
event.dataTransfer.files 是标准 FileList 对象HTML5 拖放 API 中,只要用户一次拖入多个文件(比如从桌面框选 5 个图片拖进页面),event.dataTransfer.files 就会是一个类数组的 FileList 对象,不是普通数组,不能直接用 forEach 或展开运算符(除非显式转换)。
常见错误是写成:
event.dataTransfer.files.forEach(file => { ... })——这会报 TypeError: files.forEach is not a function。
FileList 支持 length 属性和数字索引访问(files[0], files[1])Array.prototype,所以没有 map/filter/forEach
FileList 的三种可靠写法核心原则:别强转数组再遍历,优先用原生支持方式,避免不必要的内存开销(尤其大文件列表)。
for 循环(最轻量、无兼容风险):const files = event.dataTransfer.files;
for (let i = 0; i < files.length; i++) {
const file = files[i];
console.log(file.name, file.size, file.type);
}Array.from() 转为数组(ES6+,可链式调用):Array.from(event.dataTransfer.files).forEach(file => {
if (file.type.startsWith('image/')) {
handleImage(file);
}
});[...event.dataTransfer.files].map(file => ({
name: file.name,
size: file.size
}));FileList 和 的行为完全一致这点常被忽略:无论是拖放还是点击 选多个文件,得到的 files 都是同一个 FileList 类型。这意味着你封装的文件处理逻辑可以复用。
item(index) 方法(等价于 [index])files.push(...) 会失败)files.length 可能为 0,记得判空webkitGetAsEntry 不适用于多文件遍历场景有些教程提到用 event.dataTransfer.items + webkitGetAsEntry() 来递归读取目录结构,但这属于“高级拖放”能力,且:
items 是 DataTransferItemList,和 files
是平行关系,不是替代关系webkitGetAsEntry 在 Firefox 和新版 Safari 中不支持,Chrome 也仅限本地文件系统(非所有拖入文件都能 entry 化)files 已包含全部元信息(name、size、lastModified、type),无需绕路真正需要 items 的场景只有:你想区分拖入的是文件还是目录,或要读取剪贴板中的 HTML 片段等非文件数据。