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

多图上传已实现预览功能,如何点击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>&times;</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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 11:27:02