JavaScript多文件上传:新增文件时input丢失已选文件问题求助
解决文件输入重置丢失已选文件的问题
问题原因
浏览器出于安全限制,不允许修改文件输入框的files属性,每次选择新文件时,输入框会重置为当前选择的文件集合,导致之前的文件丢失。因此我们需要手动维护一个全局数组来存储所有已选择的文件。
修改后的完整代码
HTML(无需改动)
<input type="file" multiple id="gallery-photo-add" name="file[]" class="form-control custom-file-input btn btn-info" value="">
JavaScript
// 全局数组存储所有已选择的文件 let selectedFiles = []; var imagesPreview = function (files) { if (files.length > 0) { // 移除默认占位图 $('.no-image').parent().remove(); const filesAmount = files.length; const totalItens = $('.carousel-inner > .item').length; const itensSum = filesAmount + totalItens; // 更新标题中的文件总数 $('.slider-total-items > span').html(`(${itensSum})`); // 遍历每个新选择的文件 for (let i = 0; i < filesAmount; i++) { const file = files[i]; const reader = new FileReader(); reader.onload = function (event) { $('.carousel-inner > .item').removeClass('active'); let html = ''; // 处理视频文件 if (file.type.startsWith('video/')) { html = `<div class="item ${i === 0 ? 'active' : ''}"> <video width="320" height="210" controls> <source src="${event.target.result}"> </video> </div>`; } else { // 处理图片文件,确定激活状态 const isActive = (totalItens === 0 && i === 0) || (filesAmount > 1 && i === filesAmount - 1) || (filesAmount === 1 && i === 0); html = `<div class="item text-center posts-images-edit ${isActive ? 'active' : ''}"> <img src="${event.target.result}"> </div>`; } $(html).appendTo('.carousel-inner'); }; // 显示轮播控件(如果文件数量大于1) if (itensSum > 1) { $('#galleryControls').removeClass('hide'); } reader.readAsDataURL(file); } } }; $(function () { $('#gallery-photo-add').on('change', function () { if (!this.files.length) return; // 将新选择的文件添加到全局数组 selectedFiles.push(...Array.from(this.files)); // 预览新选择的文件 imagesPreview(this.files); // 重置输入框,允许重复选择相同文件 this.value = ''; }); // 表单提交处理(示例) $('#your-form-id').on('submit', function (e) { e.preventDefault(); const formData = new FormData(); // 将所有已选文件添加到FormData selectedFiles.forEach(file => { formData.append('file[]', file); }); // 添加其他表单字段(如果需要) // formData.append('other-field', $('#other-field').val()); // AJAX提交 $.ajax({ url: this.action, method: this.method, data: formData, processData: false, contentType: false, success: function (res) { // 处理成功逻辑 console.log('上传成功', res); }, error: function (xhr) { // 处理错误逻辑 console.error('上传失败', xhr); } }); }); });
关键改动说明
- 全局文件数组:新增
selectedFiles数组,用于累积所有用户选择的文件。 - 修复FileReader异步问题:在循环内为每个文件创建独立的
FileReader实例,并使用let声明循环变量,避免闭包导致的文件引用错误。 - 重置输入框:每次选择文件后重置输入框的值,允许用户重复选择相同的文件。
- 表单提交处理:通过
FormData手动添加所有已选文件,确保提交时包含全部文件。
内容的提问来源于stack exchange,提问作者Filipe
相关产品推荐
相关产品推荐

