JS DOM节点操作完全指南:增删改查与性能优化

前言

DOM节点操作是JavaScript动态操作网页的核心技术。本文系统讲解节点的创建与添加 、替换与删除 、克隆复制 以及多种创建方式的对比,最后给出性能优化的建议。掌握这些内容,你就能轻松实现页面的动态内容管理。


一、创建和添加节点

1.1 创建节点

创建元素节点
复制代码
document.createElement('标签名');
  • 参数:标签名字符串(如 'div'、'li'、'span')
  • 返回值:新创建的元素节点对象
  • 这些元素原先不存在,是根据需求动态生成的
创建文本节点
复制代码
document.createTextNode('文本内容');
  • 参数:文本内容字符串
  • 返回值:新创建的文本节点对象

1.2 添加节点

appendChild() --- 末尾追加

将一个节点添加到指定父节点的子节点列表的末尾,类似于数组的 push() 方法,也类似于CSS中的 ::after 伪元素。

复制代码
father.appendChild(child);
insertBefore() --- 指定位置插入

将一个节点添加到父节点的指定子节点前面,类似于CSS中的 ::before 伪元素。

复制代码
father.insertBefore(newNode, referenceNode);

1.3 完整示例

复制代码
let box = document.querySelector(".box");
let p = document.querySelector("p");
let btns = document.querySelectorAll("button");

// 需求1:在段落p后面追加span标签
btns[0].onclick = function() {
    // 1.1 创建span元素节点
    let spanEle = document.createElement("span");
    // 1.2 创建文本节点
    let spanText = document.createTextNode("我是一个span");
    // 1.3 将文本节点添加到span元素中
    spanEle.appendChild(spanText);
    // 1.4 将span元素追加到父容器末尾
    box.appendChild(spanEle);
};

// 需求2:在段落p前面添加h1标签
btns[1].onclick = function() {
    // 2.1 创建h1元素节点
    let h1Ele = document.createElement("h1");
    // 2.2 创建文本节点
    let h1Text = document.createTextNode("我是一个h1");
    // 2.3 将文本放入h1节点
    h1Ele.appendChild(h1Text);
    // 2.4 在p标签前插入h1
    box.insertBefore(h1Ele, p);
};

1.4 方法速查

方法 功能 类比
appendChild(child) 在父元素末尾追加子节点 数组的push()
insertBefore(new, ref) 在指定子节点前插入新节点 CSS的::before

二、替换和删除节点

2.1 替换节点 --- replaceChild()

使用指定的子节点替换已有的子节点。

复制代码
父节点.replaceChild(新节点, 旧节点);

let ul = document.querySelector("ul");
let jpm = document.getElementById("jpm"); // 要替换的旧节点

btns[0].onclick = function() {
    // 创建新的li元素
    let liEle = document.createElement("li");
    let liText = document.createTextNode("《水浒传》");
    liEle.appendChild(liText);
    
    // 替换节点:用新节点替换指定节点
    ul.replaceChild(liEle, jpm);
};

2.2 删除节点 --- removeChild()

从DOM中删除一个子节点,返回被删除的节点。

两种写法:

复制代码
// 写法一:通过父元素删除
father.removeChild(child);

// 写法二:通过节点自身的parentNode属性删除
child.parentNode.removeChild(child);

btns[1].onclick = function() {
    // 方法一:直接通过父元素删除
    ul.removeChild(jpm);
    
    // 方法二:通过节点的parentNode属性删除
    jpm.parentNode.removeChild(jpm);
};

2.3 方法速查

方法 功能 返回值
replaceChild(new, old) 用新节点替换旧节点 被替换的旧节点
removeChild(child) 删除指定子节点 被删除的节点

三、克隆节点

3.1 cloneNode() 方法

返回调用该方法的节点的一个副本。

复制代码
node.cloneNode(deep);

参数说明:

参数值 含义 说明
false(默认) 浅拷贝 只克隆节点本身,不克隆子节点
true 深拷贝 克隆节点及其所有子节点

3.2 完整示例

复制代码
document.querySelector("button").onclick = function() {
    let box = document.querySelector(".box");
    
    // 浅拷贝:只拷贝节点本身(不包含子元素)
    let boxCloneShallow = box.cloneNode(); // 默认false
    
    // 深拷贝:拷贝节点及所有子节点
    let boxCloneDeep = box.cloneNode(true);
    
    // 将克隆的节点添加到DOM中
    box.parentNode.appendChild(boxCloneDeep);
};

3.3 深浅拷贝对比

拷贝方式 参数 克隆内容 应用场景
浅拷贝​ false 仅节点外壳 需要空容器模板时
深拷贝​ true 节点及所有后代 复制完整的组件结构

四、创建节点的其他方式

4.1 innerHTML

允许更改HTML元素的内容,可以设置或返回元素开始和结束标签之间的HTML,可以解析HTML标签。

复制代码
// 获取HTML内容(包含标签)
let test1 = ul.innerHTML;

// 设置HTML内容(会解析标签)
ul.innerHTML = "<li>《红楼梦》</li><li>《水浒传》</li>";

4.2 innerText

获取或设置元素的文本------以纯文本的方式直接显示,不可以解析HTML标签。

复制代码
// 获取文本内容(不包含标签)
let test2 = ul.innerText;

// 设置文本内容(不会解析标签,直接显示为文本)
ul.innerText = "<li>《红楼梦》</li>"; // 页面显示为文本字符串

4.3 document.write()

直接将内容写入页面的内容流,但文档执行完毕后使用会导致页面全部重绘。

复制代码
document.write("<h2>新内容</h2>");

警告 :如果在页面加载完成后调用 document.write(),它会覆盖整个页面内容,慎用!

4.4 insertAdjacentHTML() --- 灵活插入

insertAdjacentHTML() 可以将字符串文本转化为节点,并插入到指定位置。它不会像 innerHTML 那样替换已有节点,而是插入到指定位置。

复制代码
element.insertAdjacentHTML(position, text);

position参数:

参数值 插入位置 示意图
beforebegin 元素本身的前面(作为前一个兄弟节点) ←新·元素→
afterbegin 元素内部的开头(作为第一个子节点) 元素内↑
beforeend 元素内部的末尾(作为最后一个子节点) 元素内↓
afterend 元素本身的后面(作为后一个兄弟节点) 元素·新→
复制代码
let str = "<li>《水浒传》</li>";

// 在ul内部开头插入
ul.insertAdjacentHTML("afterbegin", str);

// 在ul内部末尾插入
ul.insertAdjacentHTML("beforeend", str);

// 在ul前面插入(作为前一个兄弟)
ul.insertAdjacentHTML("beforebegin", str);

// 在ul后面插入(作为后一个兄弟)
ul.insertAdjacentHTML("afterend", str);

4.5 创建方式对比

方式 是否解析HTML 是否替换现有内容 性能
createElement ✅ 需手动添加 ❌ 不替换 较好
innerHTML ✅ 解析 ✅ 会替换 一般
innerText ❌ 不解析 ✅ 会替换 一般
document.write() ✅ 解析 ✅ 可能重绘 差
insertAdjacentHTML ✅ 解析 ❌ 不替换 较好

五、性能优化与最佳实践

5.1 核心方法汇总

操作 方法 说明
创建节点​ createElement() 创建元素节点
createTextNode() 创建文本节点
添加节点​ appendChild() 末尾追加
insertBefore() 指定位置插入
替换节点​ replaceChild() 替换子节点
删除节点​ removeChild() 删除子节点
克隆节点​ cloneNode() 复制节点(深浅拷贝)

5.2 性能优化建议

场景 建议 原因
大量DOM操作​ 使用 DocumentFragment 减少回流和重绘次数
批量添加​ 拼接HTML后用 innerHTML 一次性插入 减少DOM操作次数
灵活插入​ 使用 insertAdjacentHTML 不替换现有内容,性能更好
避免频繁操作​ 合并多次修改为一次操作 减少浏览器渲染压力

5.3 实际应用场景

场景 推荐方案
动态加载列表内容 createElement + appendChild
模板渲染 innerHTML 或 insertAdjacentHTML
列表项增删改查 removeChild + replaceChild
动态表单生成 createElement 逐项构建
复制组件结构 cloneNode(true) 深拷贝

总结

本文系统梳理了JavaScript DOM节点操作的完整知识体系:

主题 核心要点
创建节点​ createElement() 创建元素,createTextNode() 创建文本
添加节点​ appendChild() 末尾追加,insertBefore() 指定位置插入
替换删除​ replaceChild() 替换,removeChild() 删除
克隆节点​ cloneNode(false) 浅拷贝,cloneNode(true) 深拷贝
其他方式​ innerHTML、innerText、insertAdjacentHTML 各有优劣
性能优化​ DocumentFragment、批量操作、合理选择创建方式

掌握这些内容,你就能灵活地通过JavaScript动态操控网页内容。

相关推荐
mantou13216 小时前
我给 AI Agent 做了个「油猴」:让 Claude Code / Codex 直接用你已登录的浏览器
前端·javascript·后端
默_笙16 小时前
🍕 一个主编、三个工种、两本手册:搭一支 AI 调研队
前端·javascript
晚安日记wanna16 小时前
MySQL 回表为什么这么慢?5 种优化手段逐个拆解
数据库·mysql·性能优化
晚安日记wanna16 小时前
索引建了却不走?7 个失效原因逐层排查
数据库·mysql·性能优化
工作10年+,存储芯片行业16 小时前
Linux NVMe 中断排查与性能优化:CPU 亲和性
linux·运维·服务器·windows·性能优化·ssd·pcie
code2cat17 小时前
Java进阶篇之AtomicMarkableReference:引用还在,标记已经改变
java·开发语言·cas·并发编程·逻辑删除
CappuccinoRose17 小时前
FormData数据处理
开发语言·前端·javascript·表单数据
Zguigo17 小时前
【CUDA8】第一个CUDA C++ Kernel --vector add
java·开发语言·c++
-Marks-18 小时前
【C++编程】STL容器(二)--- vector底层模拟实现(常用接口实现 | 扩容机制 | 深浅拷贝 | 迭代器失效)
开发语言·c++·vector·内存管理·迭代器失效·vector底层模拟实现
飘尘18 小时前
SVG和Canvas,前端里的两支“画笔”,用的时候怎么选择?
前端·javascript·面试