基于JavaScript实现文件上传去重功能的问题求助
多文件上传重复检测报错求助
现有可正常运行的HTML与JavaScript代码,支持多文件上传并生成附件列表。现需添加重复文件检测逻辑,当用户选择重复文件时弹出提示。参考相关方案编写代码后,在arr.push(input.files[0].name);行出现错误,疑似混淆了this与input的引用,多次尝试未解决,求助。
原有可用代码
HTML
<input type="file" name="files" multiple id="my_files"> <ul id="file_list"> <ul id="file_names"> </ul> </ul>
注:原代码中文件输入框缺少
id="my_files",此处补充以匹配JS选择器
JavaScript
const dt = new DataTransfer(); $("#my_files").on('change', function(e){ for(var i = 0; i < this.files.length; i++){ let filearea = $('<ul/>', {class: 'attachmentname3'}), fileName = $('<ul/>', {class: 'attachmentname3', text: this.files.item(i).name}); filearea.append('<ul class="button125">Delete</ul>') .append(fileName); $("#file_list > #file_names").append(filearea); }; for (let file of this.files) { dt.items.add(file); } this.files = dt.files; });
尝试的去重代码
const dt = new DataTransfer(); $("#my_files").on('change', function(e){ var arr = []; var fileInputs = document.querySelectorAll(".attachmentname3"); fileInputs.forEach(function(input){ if(arr.length == 0){ arr.push(input.files[0].name); let filearea = $('<ul/>', {class: 'attachmentname3'}), fileName = $('<ul/>', {class: 'attachmentname3', text: input.files[0].name}); filearea.append('<ul class="button125">Delete</ul>').append(fileName); $("#file_list > #file_names").append(filearea); for (let file of input.files) { dt.items.add(file); } input.files = dt.files; } else { if(arr.indexOf(input.files[0].name) > -1){ e.preventDefault(); alert("不能上传重复文件。"); } else { arr.push(input.files[0].name); let filearea = $('<ul/>', {class: 'attachmentname3'}), fileName = $('<ul/>', {class: 'attachmentname3', text: input.files[0].name}); filearea.append('<ul class="button125">Delete</ul>').append(fileName); $("#file_list > #file_names").append(filearea); for (let file of input.files) { dt.items.add(file); } input.files = dt.files; } }; }); });
报错原因
报错位置arr.push(input.files[0].name);的核心问题是:input变量是通过document.querySelectorAll(".attachmentname3")获取的文件列表展示元素(<ul>标签),而非文件输入框,这类元素没有files属性,自然无法访问input.files[0].name,属于混淆了文件输入控件与列表展示元素的引用。
修正后的代码
JavaScript
const dt = new DataTransfer(); // 存储已上传的文件名,用于重复检测 const uploadedFileNames = []; $("#my_files").on('change', function(e){ const currentFiles = Array.from(this.files); // 遍历当前选中的文件 currentFiles.forEach(file => { // 检测文件名是否重复 if (uploadedFileNames.includes(file.name)) { alert(`不能上传重复文件:${file.name}`); return; } // 添加到已上传列表 uploadedFileNames.push(file.name); dt.items.add(file); // 更新DOM,添加文件条目 let filearea = $('<ul/>', {class: 'attachmentname3'}), fileName = $('<ul/>', {class: 'attachmentname3', text: file.name}); filearea.append('<ul class="button125">Delete</ul>') .append(fileName); $("#file_list > #file_names").append(filearea); }); // 更新文件输入框的文件列表 this.files = dt.files; });
关键修正点
- 新增
uploadedFileNames数组专门存储已上传文件名,用于快速重复检测 - 直接处理当前文件输入框选中的文件列表(
this.files),不再错误操作列表展示元素 - 逐个检测文件是否重复,重复则弹窗提示并跳过,否则正常添加到上传队列和DOM中
内容的提问来源于stack exchange,提问作者Steve Smith
相关产品推荐
相关产品推荐

