如何将图片删除的点击事件监听移至同级移除按钮?
问题:将图片删除功能从点击图片转移到点击“X”按钮,并同步更新FileList
我开发了一个带图片预览的文件上传器,当前点击预览图片时,会删除图片预览,并通过第二个数组重置FileList,表单提交前能正常移除对应图片。
背景
为简化代码,我曾移除“移除图片”按钮,设置成点击图片本身同时删除视觉预览和FileList中的图片。现在想把这个功能转移到点击“X”按钮时触发,但遇到了问题。
当前点击图片能实现预期效果,我已经把每张图片预览包裹在父级<figure>元素里,加入了类名为.remove-image的“X”按钮。底部注释的代码取消后,点击“X”能删除包含图片的<figure>元素,但没法同步更新FileList。
需求
如何实现**仅点击“X”(.remove-image元素)**时触发删除图片预览和更新FileList的功能,而不是点击图片或“X”都触发?
我知道要给.remove-image加点击事件,通过closest找到父级figure,再获取里面的图片,但只想让点击“X”时触发这个功能。
解决方案
核心修改点:
- 移除图片上的点击事件,给“X”按钮绑定点击事件
- 在点击事件中从
figure里获取对应图片的文件名,同步更新submitData和attachFiles.files - 直接删除整个
figure元素来移除预览
修改后的完整代码如下:
HTML
<form enctype="multipart/form-data" method="post" id="upload-images-form"> <input id="attach-files" type="file" name="attach-files[]" multiple> <button name="submit" id="submit">SUBMIT</button> <div id="show-selected-images"></div> </form>
CSS
* { position: relative; } form { padding: 1rem 2rem; width: 50%; border: 1px solid; } input, button { display: block; margin: 2rem 0; } .remove-image { background: #000; width: 30px; height: 30px; color: #fff; display: flex; align-items: center; justify-content: center; cursor: pointer; top: 10px; left: -10px; position: absolute; z-index: 2; } .img { width: 200px; height: 200px; object-fit: cover; margin: 0 1rem; }
JavaScript
let attachFiles = document.getElementById("attach-files"); let previewWrapper = document.getElementById("show-selected-images"); let form = document.getElementById("upload-images-form"); let submitData = new DataTransfer(); attachFiles.addEventListener("change", (e) => { const currentSubmitData = Array.from(submitData.files); // 给每个新增文件去重后添加到submitData [...e.target.files].forEach((file) => { if (currentSubmitData.every((currFile) => currFile.name !== file.name)) { submitData.items.add(file); } }); // 同步attachFiles的FileList和submitData attachFiles.files = submitData.files; // 清空预览容器后重新生成预览 previewWrapper.replaceChildren(); // 为每个选中的文件生成预览 [...submitData.files].forEach(showFiles); }); function showFiles(file) { let uploadImageWrapper = document.createElement("figure"); let previewImage = new Image(); // 创建X按钮元素,直接绑定事件而非用HTML字符串 let removeImage = document.createElement('div'); removeImage.className = 'remove-image'; removeImage.textContent = ' X '; // 设置图片属性 previewImage.dataset.name = file.name; previewImage.classList.add("img"); previewImage.src = URL.createObjectURL(file); // 给X按钮绑定点击事件 removeImage.addEventListener("click", () => { const fileName = previewImage.dataset.name; // 从submitData中移除对应文件 [...submitData.files].forEach((file, idx) => { if (file.name === fileName) { submitData.items.remove(idx); } }); // 重置attachFiles的FileList attachFiles.files = submitData.files; // 删除整个figure元素,移除预览 uploadImageWrapper.remove(); }); // 将元素添加到DOM previewWrapper.append(uploadImageWrapper); uploadImageWrapper.append(previewImage); uploadImageWrapper.prepend(removeImage); }
内容的提问来源于stack exchange,提问作者pjk_ok
相关产品推荐
相关产品推荐

