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 - 兼容性极好,所有支持拖放的浏览器(Chrome/Firefox/Safari/Edge)都返回该类型
遍历 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); } }); - 用扩展运算符(简洁,但注意 IE 不支持):
[...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 片段等非文件数据。










