JavaScript 操作 DOM 元素:添加、删除、替换、插入的完整方法指南

JavaScript 操作 DOM 元素:添加、删除、替换、插入的完整方法指南

一、开篇:DOM 元素操作 —— 前端页面交互的核心基石

在前端开发中,DOM(文档对象模型)是连接 JavaScript 与页面结构的桥梁,而元素的添加、删除、替换、插入是 DOM 操作中最基础也最常用的场景。无论是构建动态列表、实现组件渲染,还是处理用户交互后的页面更新,都离不开这些核心方法。

很多初学者在面对appendChildinsertBeforeremoveChild等方法时,容易混淆其用法和适用场景,甚至出现 “元素插入失败”“删除报错” 等问题。本文将系统梳理 JavaScript 中 DOM 元素操作的四大类方法(添加、删除、替换、插入),结合实战示例、使用差异和注意事项,帮你彻底掌握 DOM 元素操作的精髓。

二、第一类:添加元素 —— 向 DOM 中新增节点

添加元素的核心是将创建好的 DOM 节点(或已有节点)挂载到指定父元素下,常用方法有 4 种,各自有明确的适用场景:

1. appendChild ():追加子元素到父元素末尾

核心功能:将一个节点添加到指定父节点的子节点列表的末尾,是最基础的添加元素方法。语法parentNode.appendChild(childNode)特点

  • childNode是页面中已存在的节点,会将其从原有位置移动到新的父元素末尾(而非复制);
  • 返回值为被添加的childNode节点。

实战示例

javascript

运行

// 1. 创建新元素 const newDiv = document.createElement('div'); newDiv.className = 'new-item'; newDiv.innerText = '新增的末尾元素'; // 2. 获取父元素 const parent = document.getElementById('parent-container'); // 3. 追加到父元素末尾 const addedNode = parent.appendChild(newDiv); console.log(addedNode === newDiv); // true(返回被添加的节点) // 4. 移动已有元素(而非复制) const existingNode = document.getElementById('existing-item'); parent.appendChild(existingNode); // existingNode会从原有位置移动到parent末尾 

2. append ():灵活追加多个节点 / 字符串(ES6+)

核心功能:向父节点末尾追加一个或多个节点,或直接追加字符串(会自动转为文本节点),功能比appendChild更强大。语法parentNode.append(node1, node2, ..., string1, string2, ...)与 appendChild 的核心区别

特性appendChild()append()
支持参数数量仅支持单个节点支持多个节点 / 字符串
支持字符串直接追加不支持(需手动创建文本节点)支持(自动转为文本节点)
返回值返回被添加的节点无返回值(undefined)

实战示例

javascript

运行

const parent = document.getElementById('parent-container'); // 1. 追加多个节点 const div1 = document.createElement('div'); div1.innerText = '节点1'; const div2 = document.createElement('div'); div2.innerText = '节点2'; parent.append(div1, div2); // 2. 追加节点+字符串 const div3 = document.createElement('div'); div3.innerText = '节点3'; parent.append(div3, '直接追加的文本内容'); // 字符串自动转为文本节点 // 3. 对比appendChild(仅能单个节点) // parent.appendChild(div1, div2); // 报错:参数过多 

3. prepend ():向父元素开头追加节点 / 字符串(ES6+)

核心功能:与append()功能类似,但会将内容添加到父节点的子节点列表开头,而非末尾。语法parentNode.prepend(node1, node2, ..., string1, string2, ...)特点:支持多参数、支持字符串直接追加、无返回值,是 “向开头添加元素” 的便捷方法。

实战示例

javascript

运行

const parent = document.getElementById('parent-container'); const newItem = document.createElement('p'); newItem.innerText = '添加到开头的元素'; // 向父元素开头追加 parent.prepend(newItem, '开头的文本内容'); // 此时newItem是parent的第一个子元素 

4. appendChild vs append vs prepend 适用场景总结

  • 若需兼容低版本浏览器(如 IE11),优先使用appendChild()
  • 若需一次性添加多个元素 / 字符串,且无需兼容低版本浏览器,优先使用append()(末尾)/prepend()(开头);
  • 若需要获取被添加的节点引用,使用appendChild()append/prepend无返回值)。

三、第二类:删除元素 —— 从 DOM 中移除节点

删除元素的核心是将目标节点从其父元素中移除,常用方法有 3 种,涵盖直接删除、间接删除等场景:

1. removeChild ():父元素删除子元素(传统方法)

核心功能:通过父元素找到并删除指定的子元素,是兼容所有浏览器的传统删除方法。语法parentNode.removeChild(childNode)特点

  • 必须通过父元素调用,且需传入要删除的子元素节点;
  • 返回值为被删除的节点(可用于后续复用该节点);
  • childNode不是parentNode的子元素,会抛出NotFoundError

实战示例

javascript

运行

// 1. 获取父元素和要删除的子元素 const parent = document.getElementById('parent-container'); const childToRemove = document.getElementById('child-to-delete'); // 2. 删除子元素(推荐:先判断是否为子元素,避免报错) if (parent.contains(childToRemove)) { const removedNode = parent.removeChild(childToRemove); console.log(removedNode === childToRemove); // true(返回被删除的节点) // 可复用被删除的节点(重新添加到DOM中) // parent.appendChild(removedNode); } 

2. remove ():元素自行删除(ES6+)

核心功能:目标元素直接调用该方法,自行从 DOM 中移除,无需通过父元素操作,更简洁高效。语法childNode.remove()特点

  • 无需获取父元素,直接操作目标节点;
  • 无返回值(undefined);
  • 低版本浏览器(如 IE11)不支持,需转译或降级使用removeChild()

实战示例

javascript

运行

// 获取要删除的元素 const childToRemove = document.getElementById('child-to-delete'); // 直接删除(无需父元素) childToRemove.remove(); // 对比removeChild(需父元素) // const parent = childToRemove.parentElement; // parent.removeChild(childToRemove); 

3. 间接删除:替换法 / 清空法

场景 1:清空父元素下所有子元素(无需逐个删除)

javascript

运行

const parent = document.getElementById('parent-container'); // 方法1:innerHTML 清空(简单粗暴) parent.innerHTML = ''; // 方法2:循环删除子元素(更安全,避免innerHTML可能的XSS风险) while (parent.firstChild) { parent.removeChild(parent.firstChild); } 

场景 2:通过替换元素间接删除(后续详解replaceChild

javascript

运行

// 用空节点替换目标节点,间接实现删除 const parent = document.getElementById('parent-container'); const childToRemove = document.getElementById('child-to-delete'); const emptyNode = document.createTextNode(''); parent.replaceChild(emptyNode, childToRemove); 

4. 删除方法适用场景总结

  • 若需兼容低版本浏览器,或需要复用被删除的节点,优先使用removeChild()
  • 若无需兼容低版本浏览器,且操作简单,优先使用remove()(代码更简洁);
  • 若需清空父元素所有子元素,优先使用innerHTML = ''(简单)或循环removeChild(安全)。

四、第三类:替换元素 —— 替换 DOM 中的已有节点

替换元素是将原有节点替换为新节点,核心方法有 2 种,分别对应传统用法和现代用法:

1. replaceChild ():父元素替换子元素(传统方法)

核心功能:用新节点替换父元素中的指定子节点,是兼容所有浏览器的替换方法。语法parentNode.replaceChild(newNode, oldNode)特点

  • 必须通过父元素调用,传入 “新节点” 和 “要被替换的旧节点”;
  • 返回值为被替换的旧节点(可复用);
  • oldNode不是parentNode的子元素,会抛出NotFoundError

实战示例

javascript

运行

// 1. 创建新节点 const newNode = document.createElement('div'); newNode.className = 'new-replace-item'; newNode.innerText = '替换后的新元素'; // 2. 获取父元素和要被替换的旧节点 const parent = document.getElementById('parent-container'); const oldNode = document.getElementById('old-item'); // 3. 替换节点(先判断,避免报错) if (parent.contains(oldNode)) { const replacedNode = parent.replaceChild(newNode, oldNode); console.log(replacedNode === oldNode); // true(返回被替换的旧节点) } 

2. replaceWith ():元素自行被替换(ES6+)

核心功能:目标节点直接调用该方法,被新节点 / 字符串替换,无需通过父元素操作,更简洁。语法oldNode.replaceWith(newNode1, newNode2, ..., string1, ...)特点

  • 无需获取父元素,直接操作目标节点;
  • 支持多个新节点 / 字符串(会依次替换旧节点,添加到旧节点的原有位置);
  • 无返回值(undefined);
  • 低版本浏览器(如 IE11)不支持。

实战示例

javascript

运行

// 1. 获取要被替换的旧节点 const oldNode = document.getElementById('old-item'); // 2. 用单个新节点替换 const newNode1 = document.createElement('div'); newNode1.innerText = '单个新节点替换'; oldNode.replaceWith(newNode1); // 3. 用多个节点/字符串替换 const newNode2 = document.createElement('div'); newNode2.innerText = '新节点1'; oldNode.replaceWith(newNode2, '替换的文本', document.createElement('span')); // 此时旧节点被移除,原有位置变为 newNode2 + 文本 + span 节点 

3. 替换方法适用场景总结

  • 兼容低版本浏览器:使用replaceChild()
  • 现代项目(无需兼容 IE):使用replaceWith()(代码更简洁,支持多参数);
  • 若需要复用被替换的旧节点:使用replaceChild()(返回旧节点)。

五、第四类:插入元素 —— 在指定位置插入节点

插入元素是指在 “非开头 / 非末尾” 的自定义位置插入节点(如在某个元素之前 / 之后插入),核心方法有 2 种:

1. insertBefore ():在指定元素之前插入节点(传统方法)

核心功能:将新节点插入到父元素中 “参考节点” 的前面,是精准插入元素的基础方法。语法parentNode.insertBefore(newNode, referenceNode)关键说明

  • referenceNode:参考节点(新节点将插入到该节点之前);
  • referenceNodenull,则效果等同于appendChild()(插入到末尾);
  • 返回值为被插入的newNode节点;
  • 兼容所有浏览器。

实战示例

javascript

运行

// 1. 创建新节点 const newNode = document.createElement('div'); newNode.innerText = '插入到参考节点之前的元素'; // 2. 获取父元素和参考节点 const parent = document.getElementById('parent-container'); const referenceNode = document.getElementById('reference-item'); // 3. 插入到参考节点之前 if (parent.contains(referenceNode)) { const insertedNode = parent.insertBefore(newNode, referenceNode); console.log(insertedNode === newNode); // true } // 4. 若referenceNode为null,插入到末尾 // parent.insertBefore(newNode, null); // 等同于parent.appendChild(newNode) 

2. insertAdjacentElement ():灵活插入到元素周围(现代方法)

核心功能:将新节点插入到目标元素的前后左右四个精准位置,支持更灵活的插入场景,无需依赖父元素。语法targetElement.insertAdjacentElement(position, newNode)position 参数(4 个可选值)

position 值插入位置
'beforebegin'目标元素外部的前面(兄弟节点之前)
'afterbegin'目标元素内部的开头(子节点第一个)
'beforeend'目标元素内部的末尾(子节点最后一个)
'afterend'目标元素外部的后面(兄弟节点之后)

特点

  • 无需获取父元素,直接通过目标元素操作;
  • 插入位置更灵活(支持外部插入);
  • 返回值为被插入的newNode节点(插入失败返回null);
  • 兼容 IE9+,现代项目优先使用。

实战示例

html

预览

<!-- 初始结构 --> <div> <div>目标元素</div> </div> 

javascript

运行

const target = document.getElementById('target'); const newNode = document.createElement('div'); newNode.innerText = '插入的元素'; // 1. beforebegin:目标元素外部前面 target.insertAdjacentElement('beforebegin', newNode); // 结构变为:<div>插入的元素</div> <div>目标元素</div> // 2. afterbegin:目标元素内部开头 target.insertAdjacentElement('afterbegin', newNode); // 结构变为:<div><div>插入的元素</div>目标元素</div> // 3. beforeend:目标元素内部末尾 target.insertAdjacentElement('beforeend', newNode); // 结构变为:<div>目标元素<div>插入的元素</div></div> // 4. afterend:目标元素外部后面 target.insertAdjacentElement('afterend', newNode); // 结构变为:<div>目标元素</div> <div>插入的元素</div> 

补充:insertAdjacentHTML/Text ()—— 直接插入 HTML / 文本

  • insertAdjacentHTML(position, htmlString):直接插入 HTML 字符串(无需创建节点);
  • insertAdjacentText(position, textString):直接插入纯文本(避免 XSS 风险);

javascript

运行

const target = document.getElementById('target'); // 插入HTML target.insertAdjacentHTML('afterend', '<div>插入的HTML</div>'); // 插入文本 target.insertAdjacentText('beforebegin', '插入的纯文本'); 

3. 插入方法适用场景总结

  • 需兼容低版本浏览器,且在参考节点前插入:使用insertBefore()
  • 现代项目,需要灵活插入(尤其是外部插入):使用insertAdjacentElement()
  • 无需创建节点,直接插入 HTML / 文本:使用insertAdjacentHTML()/insertAdjacentText()
  • 仅需插入到开头 / 末尾:优先使用prepend()/append()(更简洁)。

六、实战总结:DOM 元素操作方法速查表

操作类型方法名核心特点兼容性适用场景
添加appendChild()单个节点、末尾插入、返回节点所有浏览器兼容低版本、需复用被添加节点
添加append()多节点 / 字符串、末尾插入、无返回值IE11+现代项目、批量添加到末尾
添加prepend()多节点 / 字符串、开头插入、无返回值IE11+现代项目、批量添加到开头
删除removeChild()父元素删除、返回被删节点所有浏览器兼容低版本、需复用被删节点
删除remove()自身删除、无需父元素、无返回值IE11+现代项目、简单删除操作
删除innerHTML = ''清空父元素所有子元素所有浏览器快速清空父元素(注意 XSS 风险)
替换replaceChild()父元素替换、返回旧节点所有浏览器兼容低版本、需复用旧节点
替换replaceWith()自身被替换、多节点 / 字符串、无返回值IE11+现代项目、灵活替换
插入insertBefore()参考节点前插入、返回新节点所有浏览器兼容低版本、精准插入到参考节点前
插入insertAdjacentElement()4 个位置灵活插入、无需父元素、返回新节点IE9+现代项目、外部插入 / 精准位置插入
插入insertAdjacentHTML()直接插入 HTML 字符串、4 个位置IE9+无需创建节点、快速插入 HTML 结构

七、注意事项:避免 DOM 操作的常见坑

  1. 操作不存在的节点报错:操作前先判断节点是否存在(如if (node)parent.contains(child));
  2. const声明的节点可操作const声明的是节点引用,而非节点本身,可正常执行remove()appendChild()等操作;
  3. innerHTML 的 XSS 风险:插入用户输入的内容时,优先使用textContentinsertAdjacentText(),避免 XSS 攻击。

频繁 DOM 操作导致性能损耗:多次添加 / 删除元素时,先将节点脱离 DOM(如使用文档片段DocumentFragment),批量操作后再挂载到 DOM 中;javascript运行

// 优化:用DocumentFragment批量添加节点 const fragment = document.createDocumentFragment(); for (let i = 0; i < 10; i++) { const div = document.createElement('div'); div.innerText = `批量元素${i}`; fragment.appendChild(div); } document.getElementById('parent').appendChild(fragment); // 仅一次DOM操作 

八、结尾:掌握 DOM 操作,提升前端交互能力

DOM 元素的添加、删除、替换、插入,是前端开发的基础技能,也是实现页面动态交互的核心。本文梳理的各类方法,既有兼容旧浏览器的传统用法,也有简洁高效的现代 API,掌握它们的差异和适用场景,能让你在开发中更灵活地操作 DOM,写出更高效、更健壮的代码。

值得注意的是,在现代前端框架(React、Vue)中,我们很少直接操作 DOM,但理解 DOM 操作的本质,能帮助我们更好地理解框架的底层原理,排查框架封装后的 DOM 相关问题。无论是原生开发还是框架开发,DOM 操作的基础知识都不可或缺。

最后用一句话总结:DOM 元素操作的核心是 “定位节点 + 选择合适的方法”,选对方法,既能提升开发效率,又能优化页面性能

Read more

星标超 28 万,OpenClaw 两天两次大更!适配GPT 5.4,告别“抽卡式 Prompt”

星标超 28 万,OpenClaw 两天两次大更!适配GPT 5.4,告别“抽卡式 Prompt”

整理 | 梦依丹 出品 | ZEEKLOG(ID:ZEEKLOGnews) “We don’t do small releases.” 这是 OpenClaw 在发布 2026.3.7 版本时写下的一句话。 刚刚过去的周六与周日,这个 GitHub 星标已超 28 万 的 AI Agent 开源项目再次迎来两轮重量级更新。 两天两次更新:OpenClaw 做了一次“真正的大版本升级” 打开 OpenClaw 的 GitHub 更新日志,你会发现这次版本更新的规模确实不小。在 3 月 7 日发布更新后,第二天又迅速推出 2026.3.8-beta.1 和

By Ne0inhk
为省5-10美元差点毁库!Claude一条指令删光200万条数据、网站停摆24小时,创始人坦言:全是我的错

为省5-10美元差点毁库!Claude一条指令删光200万条数据、网站停摆24小时,创始人坦言:全是我的错

编译 | 屠敏 出品 | ZEEKLOG(ID:ZEEKLOGnews) AI 时代,一次看似普通的操作,竟能让整套生产环境与近 200 万条数据瞬间「归零」。 近日,数据科学社区 DataTalks.Club 创始人 Alexey Grigorev 就遭遇了这样的惊魂时刻,他在使用 AI 编程工具 Claude Code 管理网站服务器时,意外清空了平台积累 2.5 年的核心数据,甚至连数据库快照也未能幸免,导致网站停摆整整 24 小时。 这起事故不仅在开发者社区引发热议,更给所有依赖 AI 工具与自动化运维的从业者敲响了警钟。事后,Alexey Grigorev 公开复盘了整个过程,并揭露了此次事故的核心问题。让我们一起看看。 一次看似很普通的网站迁移 这场“删库”事件的前因,其实并不复杂。

By Ne0inhk
苹果最贵手机要来了!折叠屏iPhone将于9月亮相;部分高校严禁校内使用OpenClaw;黄仁勋预言:传统软件和APP或将消失 | 极客头条

苹果最贵手机要来了!折叠屏iPhone将于9月亮相;部分高校严禁校内使用OpenClaw;黄仁勋预言:传统软件和APP或将消失 | 极客头条

「极客头条」—— 技术人员的新闻圈! ZEEKLOG 的读者朋友们好,「极客头条」来啦,快来看今天都有哪些值得我们技术人关注的重要新闻吧。(投稿或寻求报道:[email protected]) 整理 | 郑丽媛 出品 | ZEEKLOG(ID:ZEEKLOGnews) 一分钟速览新闻点! * 多所高校要求警惕 OpenClaw 安全风险,部分严禁校内使用 * 荣耀 CEO 李健:荣耀机器人全栈自研,将聚焦消费市场 * 马化腾凌晨 2 点发声:还有一批龙虾系产品陆续赶来 * 前快手语言大模型中心负责人张富峥,已加入智源人工智能研究院,负责 LLM 方向 * 最新全球 AI 应用百强榜发布,豆包/DeepSeek/千问上榜 * 苹果折叠 iPhone 将于九月亮相,融合 iPhone 与 iPad 体验

By Ne0inhk
黄仁勋公开发文:传统软件开发模式终结,参与AI不必非得拥有计算机博士学位

黄仁勋公开发文:传统软件开发模式终结,参与AI不必非得拥有计算机博士学位

AI 究竟是什么?在 NVIDIA CEO 黄仁勋看来,它早已不只是聊天机器人或某个大模型,而是一种正在迅速成形的“新型基础设施”。 近日,黄仁勋在英伟达官网发布了一篇长文,提出一个颇具形象的比喻——AI 就像一块“五层蛋糕”。从最底层的能源,到芯片、基础设施、模型,再到最上层的应用,人工智能正在形成一整套完整的产业技术栈,并像电力和互联网一样,逐渐成为现代社会的底层能力。 这也是黄仁勋自 2016 年以来公开发表的第七篇长文。在这篇文章中,他从计算机发展史与第一性原理出发,试图解释 AI 技术栈为何会演化成如今的形态,以及为什么全球正在掀起一场规模空前的 AI 基础设施建设。 在他看来,过去几十年的软件大多是预先编写好的程序:人类设计好算法,计算机按指令执行,数据被结构化存储在数据库中,通过精确查询调用。而 AI 的出现打破了这一模式——计算机开始能够理解图像、文本和声音,并根据上下文实时生成答案、推理结果甚至新的内容。 正因为智能不再是预先写好的代码,而是实时生成的能力,支撑它运行的整个计算体系也必须被重新设计。

By Ne0inhk