动态添加的Book Div删除按钮失效问题求助
动态新增书籍卡片的删除按钮失效问题
我通过JS函数创建包含标题、作者、页数信息及删除按钮的书籍卡片(Book Div),初始HTML里的4个卡片能正常删除,但动态新增的卡片点击删除按钮毫无反应,试了多种方法都没解决,相关代码如下:
原JS代码
const container = document.querySelector('.right'); let removeButtons = document.querySelectorAll('.remove'); let removeButtonsArray = Array.prototype.slice.call(removeButtons); let bookNum = 4; function addBook() { const titleAdd = document.getElementById('title-add').value; const readAdd = document.getElementById('read-add').value; const totalAdd = document.getElementById('total-add').value; if (titleAdd == '' || readAdd == '' || totalAdd == '') { alert('Complete all of the boxes'); return; } else if (readAdd > totalAdd) { alert('why are you lying? =[['); return; } const book = document.createElement('div'); book.classList.add('book'); container.appendChild(book); const xButton = document.createElement('button'); xButton.classList.add('remove'); book.appendChild(xButton); xButton.innerHTML = 'X'; const title = document.createElement('h2'); book.appendChild(title); title.innerHTML = titleAdd; const author = document.createElement('h3'); book.appendChild(author); author.innerHTML = document.getElementById('author-add').value; const pages = document.createElement('h3'); book.appendChild(pages); const pagesNumber = readAdd + '/' + totalAdd; pages.classList.add('page-num') pages.innerHTML = pagesNumber; bookNum++; removeButtons = document.querySelectorAll('.remove'); removeButtonsArray = Array.prototype.slice.call(removeButtons); } const button = document.querySelector('.add'); button.onclick = addBook; removeButtonsArray.forEach(removeButton => removeButton.addEventListener('click', function() { const remove = removeButtonsArray.indexOf(removeButton); removeButtonsArray.splice(remove, 1); document.querySelector('.book').remove(); bookNum--; }));
原HTML代码
<div class="container"> <div class="left"> <div class="title-add"> <h2>Title:</h2> <input type="text" id="title-add" name="title-add" max="30"> </div> <div class="author-add"> <h2>Author:</h2> <input type="text" id="author-add" name="author-add" max="30"> </div> <div class="pages"> <div class="pages-read"> <h3>Pages read:</h3> <input type="number" id="read-add" min="0" name="read"> </div> <div class="pages-total"> <h3>Total pages:</h3> <input type="number" id="total-add" min="1" name="total"> </div> </div> <button class="add">Add book</button> </div> <div class="right"> <div class="book"> <button class="remove">X</button> <h2 class="title">muie</h2> <h3 class="author">Csokmai Robert123</h3> <h3 class="page-num">31/316</h3> </div> <div class="book"> <button class="remove">X</button> <h2>muie</h2> <h3>Csokmai Robert</h3> <h3 class="page-num">31/316</h3> </div> <div class="book"> <button class="remove">X</button> <h2>muie</h2> <h3>Csokmai Robert</h3> <h3 class="page-num">31/316</h3> </div> <div class="book"> <button class="remove">X</button> <h2>muie</h2> <h3>Csokmai Robert</h3> <h3 class="page-num">31/316</h3> </div> </div> </div>
问题根源
页面加载时你只给初始存在的.remove按钮绑定了点击事件,动态新增的按钮并没有被绑定事件——哪怕你后来更新了removeButtonsArray,也没重新给新按钮添加事件监听。另外原删除逻辑里document.querySelector('.book').remove()会固定删除第一个卡片,不是点击按钮对应的卡片,这也是隐藏bug。
修复方案
方法1:事件委托(推荐)
把点击事件绑定到父容器.right上,利用事件冒泡机制处理所有动态生成的按钮点击,不管是初始还是新增的按钮都能生效:
修改后的完整JS代码:
const container = document.querySelector('.right'); let bookNum = 4; function addBook() { const titleAdd = document.getElementById('title-add').value; const readAdd = document.getElementById('read-add').value; const totalAdd = document.getElementById('total-add').value; // 输入校验:转成数字避免字符串比较错误 const readNum = parseInt(readAdd); const totalNum = parseInt(totalAdd); if (titleAdd === '' || isNaN(readNum) || isNaN(totalNum)) { alert('Complete all of the boxes'); return; } else if (readNum > totalNum) { alert('why are you lying? =[['); return; } const book = document.createElement('div'); book.classList.add('book'); container.appendChild(book); const xButton = document.createElement('button'); xButton.classList.add('remove'); book.appendChild(xButton); xButton.innerHTML = 'X'; const title = document.createElement('h2'); book.appendChild(title); title.innerHTML = titleAdd; const author = document.createElement('h3'); book.appendChild(author); author.innerHTML = document.getElementById('author-add').value; const pages = document.createElement('h3'); book.appendChild(pages); const pagesNumber = `${readAdd}/${totalAdd}`; pages.classList.add('page-num'); pages.innerHTML = pagesNumber; bookNum++; } const button = document.querySelector('.add'); button.onclick = addBook; // 事件委托:父容器监听点击,判断目标是否为删除按钮 container.addEventListener('click', function(e) { if (e.target.classList.contains('remove')) { // 找到按钮所在的书籍卡片并删除 const targetBook = e.target.closest('.book'); targetBook.remove(); bookNum--; } });
方法2:创建按钮时直接绑定事件
在动态生成.remove按钮的同时,直接给它添加点击事件:
// 在addBook函数中创建xButton后添加这段代码 xButton.addEventListener('click', function() { // 删除当前按钮的父元素(书籍卡片) this.parentElement.remove(); bookNum--; });
这种方法无需修改原有事件绑定逻辑,但每个新增按钮都要单独绑定事件,大量动态元素场景下效率略低于事件委托。
内容的提问来源于stack exchange,提问作者Robert Csokmai
相关产品推荐
相关产品推荐

