跳到主要内容JavaScript DOM 元素操作:添加、删除、替换与插入详解 | 极客日志JavaScript大前端
JavaScript DOM 元素操作:添加、删除、替换与插入详解
系统梳理了 JavaScript 中 DOM 元素操作的四大类方法:添加(appendChild, append, prepend)、删除(removeChild, remove)、替换(replaceChild, replaceWith)及插入(insertBefore, insertAdjacentElement)。文章对比了传统方法与 ES6+ 新 API 的差异、兼容性及应用场景,并提供了实战代码示例与性能优化建议(如 DocumentFragment),帮助开发者掌握核心技能以提升页面交互能力。
DataScient6 浏览 JavaScript 操作 DOM 元素:添加、删除、替换、插入的完整方法指南
一、开篇:DOM 元素操作 —— 前端页面交互的核心基石
在前端开发中,DOM(文档对象模型)是连接 JavaScript 与页面结构的桥梁,而元素的添加、删除、替换、插入是 DOM 操作中最基础也最常用的场景。无论是构建动态列表、实现组件渲染,还是处理用户交互后的页面更新,都离不开这些核心方法。
很多初学者在面对 、、 等方法时,容易混淆其用法和适用场景,甚至出现'元素插入失败''删除报错'等问题。本文将系统梳理 JavaScript 中 DOM 元素操作的四大类方法(添加、删除、替换、插入),结合实战示例、使用差异和注意事项,帮你彻底掌握 DOM 元素操作的精髓。
appendChild
insertBefore
removeChild
二、第一类:添加元素 —— 向 DOM 中新增节点
添加元素的核心是将创建好的 DOM 节点(或已有节点)挂载到指定父元素下,常用方法有 4 种,各自有明确的适用场景:
1. appendChild():追加子元素到父元素末尾
核心功能:将一个节点添加到指定父节点的子节点列表的末尾,是最基础的添加元素方法。语法:parentNode.appendChild(childNode)特点:
- 若
childNode 是页面中已存在的节点,会将其从原有位置移动到新的父元素末尾(而非复制);
- 返回值为被添加的
childNode 节点。
const newDiv = document.createElement('div');
newDiv.className = 'new-item';
newDiv.innerText = '新增的末尾元素';
const parent = document.getElementById('parent-container');
const addedNode = parent.appendChild(newDiv);
console.log(addedNode === newDiv);
const existingNode = document.getElementById('existing-item');
parent.appendChild(existingNode);
2. append():灵活追加多个节点 / 字符串(ES6+)
核心功能:向父节点末尾追加一个或多个节点,或直接追加字符串(会自动转为文本节点),功能比 appendChild 更强大。语法:parentNode.append(node1, node2, ..., string1, string2, ...)与 appendChild 的核心区别:
| 特性 | appendChild() | append() |
|---|
| 支持参数数量 | 仅支持单个节点 | 支持多个节点 / 字符串 |
| 支持字符串直接追加 | 不支持(需手动创建文本节点) | 支持(自动转为文本节点) |
| 返回值 | 返回被添加的节点 | 无返回值(undefined) |
const parent = document.getElementById('parent-container');
const div1 = document.createElement('div');
div1.innerText = '节点 1';
const div2 = document.createElement('div');
div2.innerText = '节点 2';
parent.append(div1, div2);
const div3 = document.createElement('div');
div3.innerText = '节点 3';
parent.append(div3, '直接追加的文本内容');
3. prepend():向父元素开头追加节点 / 字符串(ES6+)
核心功能:与 append() 功能类似,但会将内容添加到父节点的子节点列表开头,而非末尾。语法:parentNode.prepend(node1, node2, ..., string1, string2, ...)特点:支持多参数、支持字符串直接追加、无返回值,是'向开头添加元素'的便捷方法。
const parent = document.getElementById('parent-container');
const newItem = document.createElement('p');
newItem.innerText = '添加到开头的元素';
parent.prepend(newItem, '开头的文本内容');
4. appendChild vs append vs prepend 适用场景总结
- 若需兼容低版本浏览器(如 IE11),优先使用
appendChild();
- 若需一次性添加多个元素 / 字符串,且无需兼容低版本浏览器,优先使用
append()(末尾)/prepend()(开头);
- 若需要获取被添加的节点引用,使用
appendChild()(append/prepend 无返回值)。
三、第二类:删除元素 —— 从 DOM 中移除节点
删除元素的核心是将目标节点从其父元素中移除,常用方法有 3 种,涵盖直接删除、间接删除等场景:
1. removeChild():父元素删除子元素(传统方法)
核心功能:通过父元素找到并删除指定的子元素,是兼容所有浏览器的传统删除方法。语法:parentNode.removeChild(childNode)特点:
- 必须通过父元素调用,且需传入要删除的子元素节点;
- 返回值为被删除的节点(可用于后续复用该节点);
- 若
childNode 不是 parentNode 的子元素,会抛出 NotFoundError。
const parent = document.getElementById('parent-container');
const childToRemove = document.getElementById('child-to-delete');
if (parent.contains(childToRemove)) {
const removedNode = parent.removeChild(childToRemove);
console.log(removedNode === childToRemove);
}
2. remove():元素自行删除(ES6+)
核心功能:目标元素直接调用该方法,自行从 DOM 中移除,无需通过父元素操作,更简洁高效。语法:childNode.remove()特点:
- 无需获取父元素,直接操作目标节点;
- 无返回值(undefined);
- 低版本浏览器(如 IE11)不支持,需转译或降级使用
removeChild()。
const childToRemove = document.getElementById('child-to-delete');
childToRemove.remove();
3. 间接删除:替换法 / 清空法
const parent = document.getElementById('parent-container');
parent.innerHTML = '';
while (parent.firstChild) {
parent.removeChild(parent.firstChild);
}
场景 2:通过替换元素间接删除(后续详解 replaceChild)
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。
const newNode = document.createElement('div');
newNode.className = 'new-replace-item';
newNode.innerText = '替换后的新元素';
const parent = document.getElementById('parent-container');
const oldNode = document.getElementById('old-item');
if (parent.contains(oldNode)) {
const replacedNode = parent.replaceChild(newNode, oldNode);
console.log(replacedNode === oldNode);
}
2. replaceWith():元素自行被替换(ES6+)
核心功能:目标节点直接调用该方法,被新节点 / 字符串替换,无需通过父元素操作,更简洁。语法:oldNode.replaceWith(newNode1, newNode2, ..., string1, ...)特点:
- 无需获取父元素,直接操作目标节点;
- 支持多个新节点 / 字符串(会依次替换旧节点,添加到旧节点的原有位置);
- 无返回值(undefined);
- 低版本浏览器(如 IE11)不支持。
const oldNode = document.getElementById('old-item');
const newNode1 = document.createElement('div');
newNode1.innerText = '单个新节点替换';
oldNode.replaceWith(newNode1);
const newNode2 = document.createElement('div');
newNode2.innerText = '新节点 1';
oldNode.replaceWith(newNode2, '替换的文本', document.createElement('span'));
3. 替换方法适用场景总结
- 兼容低版本浏览器:使用
replaceChild();
- 现代项目(无需兼容 IE):使用
replaceWith()(代码更简洁,支持多参数);
- 若需要复用被替换的旧节点:使用
replaceChild()(返回旧节点)。
五、第四类:插入元素 —— 在指定位置插入节点
插入元素是指在'非开头 / 非末尾'的自定义位置插入节点(如在某个元素之前 / 之后插入),核心方法有 2 种:
1. insertBefore():在指定元素之前插入节点(传统方法)
核心功能:将新节点插入到父元素中'参考节点'的前面,是精准插入元素的基础方法。语法:parentNode.insertBefore(newNode, referenceNode)关键说明:
referenceNode:参考节点(新节点将插入到该节点之前);
- 若
referenceNode 为 null,则效果等同于 appendChild()(插入到末尾);
- 返回值为被插入的
newNode 节点;
- 兼容所有浏览器。
const newNode = document.createElement('div');
newNode.innerText = '插入到参考节点之前的元素';
const parent = document.getElementById('parent-container');
const referenceNode = document.getElementById('reference-item');
if (parent.contains(referenceNode)) {
const insertedNode = parent.insertBefore(newNode, referenceNode);
console.log(insertedNode === newNode);
}
2. insertAdjacentElement():灵活插入到元素周围(现代方法)
核心功能:将新节点插入到目标元素的前后左右四个精准位置,支持更灵活的插入场景,无需依赖父元素。语法:targetElement.insertAdjacentElement(position, newNode)position 参数(4 个可选值):
| position 值 | 插入位置 |
|---|
| 'beforebegin' | 目标元素外部的前面(兄弟节点之前) |
| 'afterbegin' | 目标元素内部的开头(子节点第一个) |
| 'beforeend' | 目标元素内部的末尾(子节点最后一个) |
| 'afterend' | 目标元素外部的后面(兄弟节点之后) |
- 无需获取父元素,直接通过目标元素操作;
- 插入位置更灵活(支持外部插入);
- 返回值为被插入的
newNode 节点(插入失败返回 null);
- 兼容 IE9+,现代项目优先使用。
<div>
<div>目标元素</div>
</div>
const target = document.getElementById('target');
const newNode = document.createElement('div');
newNode.innerText = '插入的元素';
target.insertAdjacentElement('beforebegin', newNode);
target.insertAdjacentElement('afterbegin', newNode);
target.insertAdjacentElement('beforeend', newNode);
target.insertAdjacentElement('afterend', newNode);
补充:insertAdjacentHTML/Text()—— 直接插入 HTML / 文本
insertAdjacentHTML(position, htmlString):直接插入 HTML 字符串(无需创建节点);
insertAdjacentText(position, textString):直接插入纯文本(避免 XSS 风险);
const target = document.getElementById('target');
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 操作的常见坑
- 操作不存在的节点报错:操作前先判断节点是否存在(如
if (node)、parent.contains(child));
const 声明的节点可操作:const 声明的是节点引用,而非节点本身,可正常执行 remove()、appendChild() 等操作;
- innerHTML 的 XSS 风险:插入用户输入的内容时,优先使用
textContent 或 insertAdjacentText(),避免 XSS 攻击。
频繁 DOM 操作导致性能损耗:多次添加 / 删除元素时,先将节点脱离 DOM(如使用文档片段 DocumentFragment),批量操作后再挂载到 DOM 中;
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 元素的添加、删除、替换、插入,是前端开发的基础技能,也是实现页面动态交互的核心。本文梳理的各类方法,既有兼容旧浏览器的传统用法,也有简洁高效的现代 API,掌握它们的差异和适用场景,能让你在开发中更灵活地操作 DOM,写出更高效、更健壮的代码。
值得注意的是,在现代前端框架(React、Vue)中,我们很少直接操作 DOM,但理解 DOM 操作的本质,能帮助我们更好地理解框架的底层原理,排查框架封装后的 DOM 相关问题。无论是原生开发还是框架开发,DOM 操作的基础知识都不可或缺。
最后用一句话总结:DOM 元素操作的核心是'定位节点 + 选择合适的方法',选对方法,既能提升开发效率,又能优化页面性能。
微信扫一扫,关注极客日志
微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
相关免费在线工具
- Keycode 信息
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
- Escape 与 Native 编解码
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
- JavaScript / HTML 格式化
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
- JavaScript 压缩与混淆
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online