JavaScript实现记账应用表格动态增删:删除按钮仅删末行问题修复
问题根因
写在addRow函数内部的所有DOM元素变量(rowElement、nameElement等)都没有用let/const声明,默认成了浏览器全局作用域的变量。
每次调用addRow新增一行时,这些全局变量会被重新赋值成最新创建的DOM节点,导致之前给老行的删除按钮绑定的点击事件里,引用的rowElement最后全部指向最近一次创建的表格行——这就是为啥不管点哪行的删除按钮,都只会删掉最后一行的核心原因。
修复方法
只需要改两个点,就能实现精准删除对应行的效果:
- 给
addRow函数内部所有DOM创建的变量加上const声明,把变量作用域锁在当前函数的执行上下文里,让每一次新增行时的变量引用都和当次创建的DOM绑定,不会被后续操作覆盖 - 把删除逻辑里硬引用闭包变量的写法,替换成从当前点击的删除按钮本身向上查找所属的
tr元素,绑定关系更稳定,完全不受作用域变量的影响
修复后的完整JavaScript代码
submitBtn = document.querySelector('#submit'); nameInput = document.querySelector('#name'); dateInput = document.querySelector('#date'); amountInput = document.querySelector('#amount'); tBody = document.querySelector('#tBody'); submitBtn.addEventListener('click', function (e) { e.preventDefault(); addRow(nameInput.value, dateInput.value, amountInput.value); }); let addRow = function (theName, theDate, theAmount) { // 为所有内部创建的DOM变量添加块级作用域声明 const rowElement = document.createElement('tr'); const nameElement = document.createElement('td'); const dateElement = document.createElement('td'); const amountElement = document.createElement('td'); const deleteElement = document.createElement('td'); const deleteBtn = document.createElement('button'); nameElement.textContent = theName; dateElement.textContent = theDate; amountElement.textContent = theAmount; deleteBtn.textContent = 'Delete'; deleteElement.append(deleteBtn); rowElement.appendChild(nameElement); rowElement.appendChild(dateElement); rowElement.appendChild(amountElement); rowElement.appendChild(deleteElement); tBody.appendChild(rowElement); deleteBtn.addEventListener('click', function (e) { e.preventDefault(); // 从触发点击的按钮本身向上定位所属行,100%匹配当前点击的删除按钮对应的表格行 e.target.closest('tr').remove(); }); nameInput.value = ""; dateInput.value = ""; amountInput.value = ""; }
实现效果
- 每个删除按钮触发点击时,都会精准定位到自己所在的那一行,不会出现跨行列删除的问题
- 块级作用域的变量声明避免了全局变量污染,后续新增再多表格行,引用关系都不会错乱
- 这种通过DOM层级查找父元素的写法,比闭包引用更鲁棒,就算后续动态插入新行、调整DOM结构,只要删除按钮还在
tr内部,删除逻辑就能正常运行
内容的提问来源于stack exchange,提问作者Alexander Ambrose
相关产品推荐
相关产品推荐

