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

多文件上传:实现带单独删除按钮的文件名列表(jQuery)

多文件上传预览区:单个文件删除功能实现方案

核心思路是维护一个可修改的文件数组,将每个文件与预览DOM元素关联,删除时同时移除DOM元素和数组中的对应文件,确保最终上传的文件集合正确。

实现步骤与代码示例

1. HTML结构

先搭建基础的文件选择、预览容器和上传按钮:

<input type="file" id="fileInput" multiple>
<div id="previewContainer"></div>
<button id="uploadBtn">开始上传</button>

2. JavaScript逻辑

通过数组管理选中的文件,处理文件选择、预览渲染和删除操作:

const fileInput = document.getElementById('fileInput');
const previewContainer = document.getElementById('previewContainer');
const uploadBtn = document.getElementById('uploadBtn');
// 用数组维护选中的文件(替代input只读的files属性)
let selectedFiles = [];

// 监听文件选择事件
fileInput.addEventListener('change', function(e) {
  const newFiles = Array.from(e.target.files);
  // 合并新选文件到已选列表(避免覆盖之前的选择)
  selectedFiles = [...selectedFiles, ...newFiles];
  renderPreviewList();
  // 清空input值,支持重复选择同一文件
  fileInput.value = '';
});

// 渲染文件预览列表
function renderPreviewList() {
  previewContainer.innerHTML = '';
  
  selectedFiles.forEach((file, index) => {
    const previewItem = document.createElement('div');
    previewItem.className = 'file-item';
    // 给删除按钮绑定文件索引,方便后续定位删除
    previewItem.innerHTML = `
      <span>${file.name}</span>
      <button class="delete-btn" data-index="${index}">删除</button>
    `;
    previewContainer.appendChild(previewItem);
  });

  // 给所有删除按钮绑定点击事件
  bindDeleteHandlers();
}

// 绑定删除按钮的点击事件
function bindDeleteHandlers() {
  document.querySelectorAll('.delete-btn').forEach(btn => {
    btn.addEventListener('click', function() {
      const fileIndex = parseInt(this.dataset.index);
      // 从数组中移除对应文件
      selectedFiles.splice(fileIndex, 1);
      // 重新渲染预览列表
      renderPreviewList();
    });
  });
}

// 上传操作(对接你的后端接口)
uploadBtn.addEventListener('click', async function() {
  if (selectedFiles.length === 0) {
    alert('请先选择文件');
    return;
  }

  const formData = new FormData();
  // 将数组中的文件添加到FormData
  selectedFiles.forEach(file => formData.append('files', file));

  try {
    const res = await fetch('/your-upload-endpoint', {
      method: 'POST',
      body: formData
    });
    const result = await res.json();
    console.log('上传成功', result);
    // 上传完成后清空列表
    selectedFiles = [];
    renderPreviewList();
  } catch (err) {
    console.error('上传失败', err);
  }
});

3. 基础样式(可选)

给预览项添加简单样式,提升交互体验:

.file-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 8px 12px;
  margin: 5px 0;
  border: 1px solid #e0e0e0;
  border-radius: 4px;
}

.delete-btn {
  background: #ff5252;
  color: #fff;
  border: none;
  border-radius: 3px;
  padding: 4px 8px;
  cursor: pointer;
}

.delete-btn:hover {
  background: #ff1744;
}

关键细节说明

  • 用selectedFiles数组替代input的files属性:因为input的FileList是只读的,无法直接删除其中的文件,数组可以自由修改。
  • 每次删除后重新渲染列表:确保文件索引与DOM元素完全对应,避免索引混乱。
  • 清空input的value:解决重复选择同一文件时无法触发change事件的问题。
  • 上传时基于数组构建FormData:保证上传的是删除后的最终文件集合。

内容的提问来源于stack exchange,提问作者Bashabi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 20:41:24