原生JavaScript多文件累加选择与提交问题求助
多文件选择后仅提交最后一批文件的解决办法
问题:实现类似Dropzone.js的多文件预览功能时,多次选择文件(比如先选3张再选3张),预览能显示全部6张,但表单提交时只发送最后选中的3张,input也只显示3个文件。
原因:原生<input type="file">的files属性是只读的,每次重新选择文件都会覆盖原有值,无法直接追加文件。
解决方案:维护一个全局数组存储所有选中的文件,提交表单时手动将所有文件加入FormData;同时修复预览逻辑中的重复添加问题。
修改后的代码
HTML
<div id="galleryImages" class="filezone"></div> <div id="galleryFile"> <input type="file" id="authorGallery" name="authorgallery[]" multiple> <button type="submit" id="submitBtn">提交表单</button> </div>
CSS(保持原样式)
.filezone { display: flex; flex-wrap: wrap; } .filezone .author-gallery-image { flex-basis: 20%; box-sizing: border-box; padding: 5px; } .author-gallery-image img { width: 100%; height: auto; border-radius: 20px; object-fit: cover; border: 3px solid transparent; cursor: pointer; transition: all ease-in-out 0.2s; }
JavaScript
// 全局数组存储所有选中的文件 let allSelectedFiles = []; const fileZone = document.querySelector(".filezone"); const fileInput = document.getElementById("authorGallery"); const submitBtn = document.getElementById("submitBtn"); fileInput.addEventListener("change", function(event) { const newFiles = Array.from(event.target.files); // 将新文件追加到全局数组 allSelectedFiles = [...allSelectedFiles, ...newFiles]; // 仅为新选中的文件生成预览 newFiles.forEach(file => { const fileItem = document.createElement("div"); fileItem.classList.add("author-gallery-image"); const thumbnail = document.createElement("img"); thumbnail.classList.add("thumbnail"); // 立即执行函数保存当前元素引用 (function(fileItem, thumbnail) { const reader = new FileReader(); reader.onload = function(e) { const img = new Image(); img.onload = function() { const canvas = document.createElement("canvas"); const ctx = canvas.getContext("2d"); canvas.width = 800; canvas.height = 800; const width = Math.min(img.width, 800); const height = Math.min(img.height, 800); const x = (img.width - width) / 2; const y = (img.height - height) / 2; ctx.drawImage(img, x, y, width, height, 0, 0, 800, 800); thumbnail.src = canvas.toDataURL("image/jpeg"); canvas = null; }; img.src = e.target.result; }; reader.readAsDataURL(file); })(fileItem, thumbnail); fileItem.appendChild(thumbnail); fileZone.appendChild(fileItem); }); }); // 自定义表单提交逻辑 submitBtn.addEventListener("click", function(e) { e.preventDefault(); const formData = new FormData(); // 将所有文件加入FormData,name与input的name保持一致 allSelectedFiles.forEach(file => { formData.append("authorgallery[]", file, file.name); }); // 替换为你的实际提交接口 fetch("你的提交URL", { method: "POST", body: formData }) .then(response => response.json()) .then(data => console.log("提交成功:", data)) .catch(err => console.error("提交失败:", err)); });
关键修改点
- 新增全局数组
allSelectedFiles,用于累计所有选中的文件,避免被input的files属性覆盖 - 移除原代码中重复添加预览元素的逻辑,仅为新选中的文件生成预览
- 提交时手动构建
FormData,将所有累计的文件加入后发送请求,替代原生表单提交逻辑
内容的提问来源于stack exchange,提问作者Designer
相关产品推荐
相关产品推荐

