如何在拖拽文件后保留file input的原有值?
问题:拖拽文件时如何保留已选文件,合并新拖拽的文件?
我用这段代码实现多文件拖拽:
document.getElementById('file-input').files = e.dataTransfer.files;代码能正常运行,但第二次拖拽文件时,旧的文件列表会被覆盖。我想保留旧值,尝试过合并两个数组,但FileList是只读的。我考虑用
new File()来创建新文件列表,但找不到正确的实现方式。
解决方案
由于FileList是只读对象,无法直接修改或合并,核心思路是用数组维护所有已选文件,再通过DataTransfer对象将数组转换为可赋值给input的FileList。
具体实现步骤
- 声明数组存储所有已选文件
// 全局或在闭包内声明,用于持久化已选文件 let selectedFiles = [];
- 处理拖拽事件,合并新文件到数组
在拖拽的drop事件处理函数中,将新拖拽的文件追加到已选数组:
function handleDrop(e) { e.preventDefault(); // 将新拖拽的FileList转为数组 const newFiles = Array.from(e.dataTransfer.files); // 合并到已选文件数组(可在这里添加去重逻辑) selectedFiles = [...selectedFiles, ...newFiles]; // 将数组转为FileList并赋值给input updateFileInput(); }
- 将数组转换为FileList并赋值给input
利用DataTransfer构建新的FileList:
function updateFileInput() { const dataTransfer = new DataTransfer(); // 把所有已选文件添加到DataTransfer selectedFiles.forEach(file => dataTransfer.items.add(file)); // 赋值给input的files属性 document.getElementById('file-input').files = dataTransfer.files; }
可选优化:避免重复文件
如果需要防止重复添加相同文件,可以在合并数组前做过滤,比如根据文件的name、size和lastModified组合判断:
const newFiles = Array.from(e.dataTransfer.files).filter(newFile => { return !selectedFiles.some(existFile => existFile.name === newFile.name && existFile.size === newFile.size && existFile.lastModified === newFile.lastModified ); }); selectedFiles = [...selectedFiles, ...newFiles];
补充说明
new File()是用于创建单个新文件的API,比如从Blob或字符串生成文件,并不适合用来合并现有FileList,所以这个方向不适用。
内容的提问来源于stack exchange,提问作者Matt Richardson
相关产品推荐
相关产品推荐

