如何向FileList追加新图片并按索引删除其中的图片?
Great question! Let's get straight to the point: the native FileList object returned by the file input is read-only—you can't directly append new files to it or delete existing ones. This is a browser security restriction to prevent unauthorized manipulation of the files a user has selected. But don't worry, we can work around this by maintaining our own array to track selected files, then using that array for all our operations.
1. 如何实现新图片的追加
Instead of relying on the FileList directly, we'll create a custom array to store all selected files. Every time the user selects new files, we'll add those files to our array.
2. 如何按索引删除图片
Since we're using our own array, we can easily use array methods like splice() to remove files by index, then re-render the preview to reflect the changes.
修改后的完整代码示例
// 我们自己维护的文件数组,用来存储所有选中的文件 let selectedFiles = []; function renderFilePreviews() { const list = document.getElementById('list'); // 清空现有预览 list.innerHTML = ''; selectedFiles.forEach((file, index) => { if (!file.type.match('image.*')) return; const reader = new FileReader(); reader.onload = (function(theFile, fileIndex) { return function(e) { // 创建包含删除按钮的预览元素 const span = document.createElement('span'); span.innerHTML = ` <img class="thumb" src="${e.target.result}" title="${escape(theFile.name)}"/> <button class="delete-btn" data-index="${fileIndex}">删除</button> `; list.appendChild(span); // 绑定删除按钮事件 span.querySelector('.delete-btn').addEventListener('click', () => { // 从数组中删除对应索引的文件 selectedFiles.splice(fileIndex, 1); // 重新渲染预览 renderFilePreviews(); }); }; })(file, index); reader.readAsDataURL(file); }); } function handleFileSelect(evt) { const files = evt.target.files; // 新选中的FileList // 将FileList转换为数组并追加到我们的selectedFiles数组中 selectedFiles.push(...files); // 重新渲染预览 renderFilePreviews(); } document.getElementById('files').addEventListener('change', handleFileSelect, false);
.thumb { height: 75px; border: 1px solid #000; margin: 10px 5px 0 0; } .delete-btn { margin-left: 5px; cursor: pointer; }
<input type="file" id="files" name="files[]" multiple /> <output id="list"></output>
代码关键点说明
selectedFiles数组: 这是我们用来替代只读FileList的核心,所有的追加、删除操作都基于这个数组。renderFilePreviews()函数: 负责根据当前selectedFiles数组的内容渲染预览图和删除按钮,每次数组变化后调用它来更新界面。- 追加文件: 使用扩展运算符(
...files)将新选中的FileList转换为数组,再用push()添加到selectedFiles中。 - 删除文件: 给每个预览图绑定删除按钮,点击时用
splice(index, 1)删除数组中对应索引的元素,然后重新渲染预览。
这样就能实现你想要的“追加新图片”和“按索引删除图片”的功能啦!
内容的提问来源于stack exchange,提问作者sonEtLumiere

