event.dataTransfer.files为空的主因是未在dragover和drop事件中均调用event.preventDefault(),浏览器默认阻止拖放行为导致无法获取文件;应优先使用files而非items,因其兼容性好且含完整文件元信息。

直接用 event.dataTransfer.files[0].name 就能拿到拖入文件的原始名称,但必须确保 drop 和 dragover 事件里都调用了 event.preventDefault(),否则 files 是空的。
为什么 event.dataTransfer.files 有时是空数组?
不是浏览器不支持,而是事件处理没拦住默认行为。浏览器在 dragover 阶段默认会拒绝接收文件数据,除非你显式阻止它。
-
dragover里漏掉event.preventDefault()→drop时event.dataTransfer.files.length === 0 - 只在
drop里加preventDefault(),但没管dragover→ 同样拿不到文件 - 监听了
change事件(那是的路径)→ 拖放场景下根本不会触发
files 和 items 该用哪个?
优先用 event.dataTransfer.files。它返回标准 FileList,每个 File 对象天然带 name、size、type、lastModified 属性,兼容性好(IE10+、所有现代浏览器)。
-
event.dataTransfer.items更底层,适合需要区分「文件」和「非文件项」(比如文本、URL)的场景 - 想读文件夹?得用
items[i].webkitGetAsEntry(),但仅限 Chrome/Edge,且需用户主动拖入整个文件夹(不是选中后拖) - 移动端完全不支持
dataTransfer.files→ 别在这儿做兼容,改用回退方案
多文件拖拽时怎么安全提取所有文件名?
别直接遍历 files 然后全塞进 FileReader —— 用户拖 50 个 100MB 文件,页面大概率卡死或崩溃。
- 先用
for (let i = 0; i 快速列出名称,不读内容 - 需要预览?用
URL.createObjectURL(files[i])生成临时 URL,比readAsDataURL节省内存 - 要校验类型?别信
files[i].type(可能为空或伪造),用files[i].name.split('.').pop().toLowerCase()做后缀判断更稳 - 注意:同一个文件被多次拖入,
name相同但lastModified可能不同,别靠名字去重
真正容易被忽略的是:拖放 API 不关心 multiple 属性,那个只对 有效;而用户是否拖多个文件,取决于操作系统层面的操作(比如 macOS 上 Cmd+点击多选再拖),前端唯一能做的,就是把 dragover 和 drop 的 preventDefault 写牢,剩下的交给浏览器原生行为。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











