You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

原生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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 16:24:55