移除div后无法新增div:原生JS支出追踪器故障求助
解决支出追踪器删除条目后添加按钮失效的问题
问题根源
你遇到的错误核心原因有两个:
- 重复使用同一ID违反HTML规范:所有克隆的条目都使用
expense-item这个ID,而getElementById只会返回第一个匹配的元素,删除操作会直接移除初始的那个条目。 - 初始元素被删除后变量失效:页面加载时
original指向初始的#expense-item,删除该元素后,original变成已被移除的DOM节点,后续调用original.parentNode会返回null,触发Cannot read properties of null (reading 'appendChild')错误。
纯JavaScript解决方案
以下是不依赖jQuery的修复方案,同时解决ID重复问题,确保功能稳定:
修改后的HTML
<main id="main"> <div class="container" id="container"> <!-- 移除重复ID,仅保留类标识 --> <div class="expense-item"> <!-- 传递当前按钮给删除函数,精准定位要删除的条目 --> <button class="delete-btn" onclick="deleteItem(this)">Delete</button> <div class="expense-inputs"> <!-- 初始条目使用唯一ID,后续克隆会自动生成新ID --> <label for="expense-name-1"></label> <input type="text" placeholder="Expense Name" name="expense-name" id="expense-name-1"> <label for="expense-category-1"></label> <select name="expense-category" id="expense-category-1"> <option value="">Category</option> <option value="groceries">Groceries</option> <option value="housing">Housing</option> <option value="utilities">Utilities</option> </select> <label for="expense-amount-1"></label> <input type="text" name="expense-amount" id="expense-amount-1" placeholder="Amount"> </div> </div> </div> <div class="info"> <div class="new-item"> <button class="new-item-btn" id="new-item-btn">New Item</button> </div> </div> </main>
修改后的JavaScript
document.getElementById('new-item-btn').addEventListener('click', duplicate); const container = document.getElementById('container'); const itemTemplate = document.querySelector('.expense-item'); let itemCount = 1; // 用于生成唯一ID的计数器 function duplicate() { itemCount++; // 克隆初始条目作为模板 const clone = itemTemplate.cloneNode(true); // 更新克隆条目中所有输入元素的唯一ID,同步对应label的for属性 const inputs = clone.querySelectorAll('input, select'); inputs.forEach(input => { const baseId = input.id.split('-').slice(0, -1).join('-'); input.id = `${baseId}-${itemCount}`; const label = clone.querySelector(`label[for="${baseId}-1"]`); if (label) label.setAttribute('for', input.id); }); // 将克隆条目添加到容器中 container.appendChild(clone); } function deleteItem(btn) { // 通过按钮找到父级的支出条目元素 const targetItem = btn.closest('.expense-item'); // 可选:保留至少一个条目,避免容器为空无法继续添加 if (container.children.length > 1) { targetItem.remove(); } }
关键修改点说明
- 移除重复ID:所有元素ID保持唯一,避免DOM查询歧义
- 精准删除条目:通过
this传递当前删除按钮,用closest('.expense-item')定位要删除的条目,不再依赖ID查找 - 模板克隆+唯一ID生成:基于初始条目克隆新元素,自动更新内部输入框和label的关联属性,符合HTML规范
- 事件绑定优化:使用
addEventListener绑定添加事件,比直接赋值onclick更灵活可靠
内容的提问来源于stack exchange,提问作者Marcelo Lins
相关产品推荐
相关产品推荐

