You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

移除div后无法新增div:原生JS支出追踪器故障求助

解决支出追踪器删除条目后添加按钮失效的问题

问题根源

你遇到的错误核心原因有两个:

  1. 重复使用同一ID违反HTML规范:所有克隆的条目都使用expense-item这个ID,而getElementById只会返回第一个匹配的元素,删除操作会直接移除初始的那个条目。
  2. 初始元素被删除后变量失效:页面加载时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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 21:05:20