多文件上传:实现带单独删除按钮的文件名列表(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
相关产品推荐
相关产品推荐

