Booklist项目点击删除后选中索引到数组末尾元素全被删除问题排查
问题根因
核心原因是删除按钮的点击事件被重复绑定:
- 每次删除操作完成后你会重新渲染所有图书卡片,渲染完成后你会调用
removeBookCard()给当前所有存在的删除按钮新增点击事件监听 - 旧的事件监听没有被清理,点击一次删除按钮就会触发多轮删除逻辑,每一轮都会删除当前数组对应索引的元素,最终表现为从目标索引到数组末尾的所有图书都被删除
- 你之前用匿名函数作为事件回调,也无法直接通过
removeEventListener清除已绑定的旧事件
修复方案
推荐使用事件委托的方案,仅需初始化绑定一次,不需要每次渲染书单都重复绑定,彻底避免重复触发问题:
// 仅在页面初始化时执行一次即可,bookContainer替换为你所有图书卡片的公共父容器DOM bookContainer.addEventListener('click', (e) => { // 替换为你删除按钮对应的类名,用来判断点击源是不是删除按钮 if (e.target.classList.contains('del-btn')) { const index = e.target.parentElement.parentElement.parentElement.dataset.index; deleteBook(myLibrary, index); clearBookContainer(); displayBooks(); } }) // 原来的removeBookCard绑定逻辑可以直接删除,不需要再调用
如果不想调整现有绑定逻辑,也可以给按钮加绑定标记,避免重复绑定:
function removeBookCard() { [...bookDelBtn].forEach((btn) => { // 已经绑定过事件的按钮直接跳过 if (btn.dataset.hasBound) return btn.dataset.hasBound = 'true' btn.addEventListener("click", (e) => { console.log("hi"); let index = e.target.parentElement.parentElement.parentElement.dataset.index; console.log(index); deleteBook(myLibrary, index); clearBookContainer(); displayBooks(); }) }); }
另外你现有的deleteBook函数写法不规范,入参arr没有被使用,直接修改了外部变量,可以调整为更通用的写法:
function deleteBook(arr, index) { return [...arr.slice(0, index), ...arr.slice(index + 1)] } // 调用时再赋值给外部变量 myLibrary = deleteBook(myLibrary, index)
内容的提问来源于stack exchange,提问作者Iwantroca
相关产品推荐
相关产品推荐

