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

JavaScript DOM操作:如何同步删除JSON数据和对应的DOM元素

功能修复方案

核心问题

  • 仅修改了内存中的数组数据,未关联删除对应的DOM节点,所以页面不会同步更新
  • 直接用idx-1作为数组下标删除逻辑有缺陷:当删除前面的条目后,后续条目的数组下标会发生变化,和userId不再匹配,会出现删错数据的问题
  • 原有删除事件绑定的写法存在冗余,不需要额外传入event参数

具体修改步骤

1. 给DOM节点添加唯一标识

在createEle函数中给每个条目根节点添加自定义属性存储userId,方便后续删除时快速定位对应的DOM:

const createEle = (data, idx) => {
  let main = document.createElement("div");
  // 新增:存储当前条目的userId,DOM上会生成data-userid属性
  main.dataset.userId = data.userId;
  let container = document.getElementById("container");
  let title = document.createElement('div');
  let age = document.createElement('div');
  let remove = document.createElement('div');
  let update = document.createElement('div');
  main.className = "main";
  title.className = "title";
  age.className = "age";
  remove.className = "delete";
  update.className = "update";

  container.appendChild(main);
  main.appendChild(title);
  main.appendChild(age);
  main.appendChild(update);
  main.appendChild(remove);

  // 简化事件绑定,不需要用bind
  remove.addEventListener("click", () => deleteEle(data.userId));

  title.append(data.name);
  age.append(data.age);
  update.append("Edit");
  remove.append("Delete");
}

2. 优化删除逻辑,同步删除DOM和数据

修改deleteEle函数,先定位到对应DOM节点删除,再删除数组中的对应数据:

const deleteEle = (userId) => {
  // 第一步:删除对应DOM节点,注意dataset属性在选择器中为全小写短横线格式
  const targetDom = document.querySelector(`.main[data-userid="${userId}"]`);
  targetDom && targetDom.remove();
  // 第二步:按userId匹配删除数组数据,避免下标错位问题
  const targetIndex = names.nameList.findIndex(item => item.userId === userId);
  if (targetIndex > -1) {
    names.nameList.splice(targetIndex, 1);
  }
  console.log("deleted", userId, names.nameList);
}

3. 优化渲染逻辑

原渲染用的map方法是用于生成新数组的,纯遍历渲染建议改用forEach,更符合语义:

const displayData = () => {
  names.nameList.forEach(data => {
    createEle(data, data.userId);
  });
}

面向对象实现示例

如果想要改用面向对象写法,可以把所有数据和操作封装到同一个类中,逻辑更内聚,后续扩展功能也更方便:

class UserManager {
  constructor() {
    this.nameList = [
      {userId: 1, name: "abc", age: "25"},
      {userId: 2, name: "def", age: "23"},
      {userId: 3, name: "ghi", age: "18"},
      {userId: 4, name: "jkl", age: "19"},
    ];
    this.container = document.getElementById("container");
  }

  #createUserItem(data) {
    const main = document.createElement("div");
    main.dataset.userId = data.userId;
    main.className = "main";

    const title = document.createElement('div');
    title.className = "title";
    title.append(data.name);

    const age = document.createElement('div');
    age.className = "age";
    age.append(data.age);

    const update = document.createElement('div');
    update.className = "update";
    update.append("Edit");

    const remove = document.createElement('div');
    remove.className = "delete";
    remove.append("Delete");
    remove.addEventListener("click", () => this.delete(data.userId));

    main.append(title, age, update, remove);
    this.container.appendChild(main);
  }

  render() {
    // 渲染前清空容器,避免后续新增/修改数据时重复渲染
    this.container.innerHTML = '';
    this.nameList.forEach(item => this.#createUserItem(item));
  }

  delete(userId) {
    // 删除DOM
    const targetDom = this.container.querySelector(`.main[data-userid="${userId}"]`);
    targetDom && targetDom.remove();
    // 删除数据
    const targetIndex = this.nameList.findIndex(item => item.userId === userId);
    targetIndex > -1 && this.nameList.splice(targetIndex, 1);
  }

  // 后续可以直接在类中扩展add、find等方法
  find() {
    console.log("Find function");
  }

  add(userInfo) {
    this.nameList.push(userInfo);
    this.render();
  }
}

// 初始化使用
const userManager = new UserManager();
userManager.render();

内容的提问来源于stack exchange,提问作者Nandakumar singh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.10 12:33:02