多图上传已实现预览功能,如何点击x按钮删除预览并同步移除数组对应项
解决方案
核心改动逻辑
- 每个图片上传到数组后,记录其在
item_images中的索引,绑定到对应删除按钮的自定义属性上 - 给删除按钮绑定点击事件,触发时依次执行三个操作:
- 释放
URL.createObjectURL创建的临时内存,避免内存泄漏 - 移除当前图片+删除按钮对应的DOM节点
- 同步删除
item_images数组中对应索引的元素
- 释放
- 多批次上传时索引自动累加,不需要额外处理顺序问题
完整修改代码
JS代码
function previewImage(e, selectedFiles, imagesArray) { const elemContainer = document.createElement('div'); elemContainer.setAttribute('class', 'item-images'); for (let i = 0; i < selectedFiles.length; i++) { // 先把文件推入数组,拿到当前文件的索引 const currentIndex = imagesArray.length; imagesArray.push(selectedFiles[i]); const elem = document.createElement('img'); const objectUrl = URL.createObjectURL(e.target.files[i]); elem.setAttribute('src', objectUrl); elem.setAttribute('class', 'item-photo__preview') const removeButton = document.createElement('button'); removeButton.setAttribute('type', 'button'); // 存储当前索引和临时url,方便后续清理 removeButton.dataset.index = currentIndex; removeButton.dataset.objectUrl = objectUrl; removeButton.innerHTML = '<span>×</span>' // 绑定删除事件 removeButton.addEventListener('click', function() { const delIndex = Number(this.dataset.index); // 1. 释放临时url内存 URL.revokeObjectURL(this.dataset.objectUrl); // 2. 移除对应的预览DOM elem.remove(); this.remove(); // 3. 同步删除数组对应元素 imagesArray.splice(delIndex, 1); // 删除元素后更新所有剩余删除按钮的index,避免后续删除错位 document.querySelectorAll('button[data-index]').forEach(btn => { const btnIndex = Number(btn.dataset.index); if (btnIndex > delIndex) { btn.dataset.index = btnIndex - 1 } }) }) elemContainer.appendChild(elem); elemContainer.appendChild(removeButton); } return elemContainer; } let item_images = []; document.querySelector('#photo-upload').addEventListener('change', (e) => { let selectedFiles = e.target.files; const photoPreviewContainer = document.querySelector('#photo-upload__preview'); const elemContainer = previewImage(e, selectedFiles, item_images); photoPreviewContainer.appendChild(elemContainer); // 清空input值,允许重复选择同一批次文件 e.target.value = ''; });
优化后的CSS(可选,修复删除按钮错位问题)
.item-images { position: relative; display: inline-block; margin-right: 10px; margin-bottom: 10px; } .item-photo__preview { width:150px; height: 150px; object-fit: cover; } .item-images button { position: absolute; top: -8px; right: -8px; width: 24px; height: 24px; border-radius: 50%; border: none; background: #000; color: #fff; cursor: pointer; display: flex; align-items: center; justify-content: center; padding: 0; }
HTML代码和原有逻辑保持一致即可
<div class="item-upload"> <input id="photo-upload" type="file" multiple/> <div id="photo-upload__preview" class="upload-preview"></div> </div>
内容的提问来源于stack exchange,提问作者zyyyzzz
相关产品推荐
相关产品推荐

