为什么JavaScript移除卡片按钮仅首次生效,后续使用报类型错误?
问题分析与修复方案
核心报错原因
你遇到的Failed to execute 'removeChild' on 'Node': parameter 1 is not of type 'Node'报错,本质是所有删除按钮的点击事件都引用了同一个全局递增的bookIndex变量:
- 每添加一本书
bookIndex就会+1,所有删除事件函数访问的都是最终的bookIndex值(比如你添加3本测试书后bookIndex最终为3) - 首次点击任意删除按钮时,只会删除id为3的书籍卡片,之后再点击其他按钮,
document.getElementById(bookIndex)会返回null,传入removeChild就触发类型错误
其他待优化问题
- 所有书籍卡片的
readBox复选框id重复,会导致label点击关联失效 removeBook函数逻辑错误:pop方法只能删除数组最后一个元素,无法删除指定书籍addBookToLibrary内声明的buttonArray、cardArray、cardID未实际使用,属于冗余代码
修复代码
只需修改addBookToLibrary函数内的模板和点击事件绑定逻辑即可:
function addBookToLibrary(Book){ myLibrary.push(Book); bookIndex = bookIndex + 1; let buttonName = "button" + bookIndex; // 模板内给复选框id加索引避免重复 let html = ` <entry id=${bookIndex}> <div> <h3>Title: ${Book.title}</h3> <h3>Author: ${Book.author}</h3> <h3>Pages: ${Book.pages}</h3> <input type="checkbox" id="readBox${bookIndex}" name = "readBox" value="Read"> <label for="readBox${bookIndex}">Read</label><br> <button id=${buttonName}>Remove</button> </div> </entry> `; var newEl = document.createElement("template"); newEl.innerHTML = html.trim(); document.getElementById('main').appendChild(newEl.content.firstChild); // 修复点击事件:把当前索引存为局部变量,避免闭包引用全局变量的问题 const currentBookIndex = bookIndex; document.getElementById(buttonName).onclick = function() { let targetEntry = document.getElementById(currentBookIndex); if(targetEntry) { document.getElementById('main').removeChild(targetEntry); // 同步删除数组内对应的书籍数据 myLibrary.splice(currentBookIndex - 1, 1); } console.log(myLibrary); } }
如果你不想依赖索引id做删除,也可以直接通过事件目标查找父元素,逻辑更稳妥:
document.getElementById(buttonName).onclick = function(e) { const targetEntry = e.target.closest('entry'); targetEntry.remove(); // 同步删除数组数据的逻辑可以自己补充 }
内容的提问来源于stack exchange,提问作者Staver
相关产品推荐
相关产品推荐

