如何实现input type="file"多次选文件并提交所有选中文件?
解决多次选择文件并批量提交的问题
你说得没错,<input type="file">的files属性是只读的,没办法直接往里面追加新文件,每次选择都会覆盖之前的选中内容。不过我们可以换个思路,不用强行把所有文件塞进同一个input里,而是用一个数组来存储所有选中的文件,提交时统一用FormData来处理上传,这样既保留了多次选择的功能,也能轻松处理删除操作。
下面是具体的实现步骤:
1. 初始化文件存储数组
首先声明一个全局数组,用来保存所有用户选中的文件:
let selectedFiles = [];
2. 修改文件选择的事件处理
更新你的change事件逻辑,把每次选中的文件追加到数组里,同时只渲染新增的文件到页面(避免重复渲染):
$("#upload-anexo").change(function() { // 把FileList转成数组方便操作 const newFiles = Array.from($(this)[0].files); // 追加新文件到全局数组 selectedFiles = [...selectedFiles, ...newFiles]; // 渲染本次选中的文件到页面 newFiles.forEach(file => { const newLine = ` <div class='anexo-line' data-filename='${file.name}'> <div class='anexo-nome-arquivo'> <i class='icon-arrow-up anexo-uploaded'></i> ${file.name} </div> <div class='anexo-actions'> <i class='icon-trash anexo-delete'></i> </div> </div> `; $("#modal-anexos .modal-body").append(newLine); }); // 清空当前input的选中值,允许用户再次选择相同文件 $(this).val(''); });
3. 实现文件删除功能
给删除按钮绑定事件,点击时从数组和页面中移除对应的文件:
// 用事件委托绑定动态生成的删除按钮 $(document).on('click', '.anexo-delete', function() { const $line = $(this).closest('.anexo-line'); const filename = $line.data('filename'); // 从全局数组中移除该文件 selectedFiles = selectedFiles.filter(file => file.name !== filename); // 移除页面上的文件行 $line.remove(); });
4. 批量提交所有文件
点击保存按钮时,把数组里的所有文件放进FormData,通过AJAX提交到后端:
$("#btn-ok-anexos").click(function() { const formData = new FormData(); // 将所有选中的文件添加到FormData selectedFiles.forEach((file, index) => { // 第二个参数是后端接收的字段名,用`anexos[]`方便后端解析为数组 formData.append('anexos[]', file, file.name); }); // 如果需要添加其他表单字段,可以在这里追加 // formData.append('someOtherField', 'yourValue'); // 发送上传请求 $.ajax({ url: '你的后端上传接口地址', type: 'POST', data: formData, // 这两个参数必须设置,否则jQuery会破坏FormData的结构 processData: false, contentType: false, success: function(response) { alert('附件上传成功!'); $('#modal-anexos').modal('hide'); // 重置状态 selectedFiles = []; $('.anexo-line').not('.anexo-line:first').remove(); // 保留初始的示例行 }, error: function(xhr, status, error) { alert(`上传失败:${error}`); } }); });
为什么不用隐藏input?
因为浏览器出于安全考虑,不允许手动修改<input type="file">的files属性,所以你没法把多个选择的文件合并到一个input里。而用数组+FormData的方式,既符合浏览器的安全规则,又能灵活管理所有选中的文件,还能轻松实现删除、去重(如果需要的话)等功能。
内容的提问来源于stack exchange,提问作者Renan Araújo
相关产品推荐
相关产品推荐

