全部学科
NodeJS全栈
nodejs
Python全栈
python
小程序首页
📅 2026-05-17 10 分钟 ✍️ juanwangdev

DOM树与节点操作

DOM树将HTML文档解析为节点树结构,JavaScript可动态操作节点。

DOM树结构

节点层级

JavaScript
Document(文档节点)
├── Element(元素节点)
│   ├── Element
│   │   └── Text(文本节点)
│   └── Element
│       ├── Comment(注释节点)
│       └── Text
└── DocumentType(文档类型)

节点类型

JavaScript
const el = document.querySelector('.box');

// 节点类型
el.nodeType;       // 1 (Element)
el.nodeName;       // 'DIV'
el.nodeValue;      // null(元素节点)

// 文本节点
const text = el.firstChild;
text.nodeType;     // 3 (Text)
text.nodeValue;    // 文本内容
nodeType类型说明
1Element元素节点
3Text文本节点
8Comment注释节点
9Document文档节点
10DocumentType文档类型
11DocumentFragment文档片段

创建节点

createElement

JavaScript
// 创建元素
const div = document.createElement('div');
const p = document.createElement('p');
const span = document.createElement('span');

// 设置属性
div.id = 'container';
div.className = 'wrapper';
div.setAttribute('data-id', '123');

createTextNode

JavaScript
// 创建文本节点
const text = document.createTextNode('Hello World');

createComment

JavaScript
// 创建注释节点
const comment = document.createComment('这是一个注释');

DocumentFragment

JavaScript
// 创建文档片段(批量操作优化)
const fragment = document.createDocumentFragment();

for (let i = 0; i < 100; i++) {
    const li = document.createElement('li');
    li.textContent = `项目${i}`;
    fragment.appendChild(li);
}

// 一次性插入
list.appendChild(fragment);

插入节点

appendChild

JavaScript
const parent = document.querySelector('.container');
const child = document.createElement('div');

// 添加到末尾
parent.appendChild(child);

// 返回插入的节点
const inserted = parent.appendChild(child);

insertBefore

JavaScript
const parent = document.querySelector('.container');
const newChild = document.createElement('div');
const refChild = parent.querySelector('.reference');

// 在refChild之前插入
parent.insertBefore(newChild, refChild);

// 插入到第一个子元素之前
parent.insertBefore(newChild, parent.firstElementChild);

// 插入到末尾(ref为null)
parent.insertBefore(newChild, null);

append/prepend

JavaScript
const parent = document.querySelector('.container');

// 末尾添加多个
parent.append(div, span, '文本');

// 开头添加多个
parent.prepend(div, span);

// 注意:append/prepend可以添加字符串(自动转为文本节点)

after/before

JavaScript
const el = document.querySelector('.item');

// 在el之后插入
el.after(div, span);

// 在el之前插入
el.before(div, span);

删除节点

removeChild

JavaScript
const parent = document.querySelector('.container');
const child = parent.querySelector('.item');

// 通过父元素删除
parent.removeChild(child);

// 返回删除的节点
const removed = parent.removeChild(child);

remove

JavaScript
const el = document.querySelector('.item');

// 直接删除
el.remove();

replaceChild

JavaScript
const parent = document.querySelector('.container');
const newChild = document.createElement('div');
const oldChild = parent.querySelector('.item');

// 替换节点
parent.replaceChild(newChild, oldChild);

replaceWith

JavaScript
const el = document.querySelector('.item');

// 替换自身
el.replaceWith(document.createElement('div'));

克隆节点

cloneNode

JavaScript
const el = document.querySelector('.box');

// 浅克隆(只克隆元素,不含子节点)
const shallow = el.cloneNode();

// 深克隆(含所有子节点)
const deep = el.cloneNode(true);

// 注意:不克隆事件监听器

节点属性操作

属性读写

JavaScript
const el = document.querySelector('.box');

// 读取属性
el.getAttribute('class');
el.getAttribute('data-id');

// 设置属性
el.setAttribute('class', 'wrapper');
el.setAttribute('data-id', '123');

// 删除属性
el.removeAttribute('data-id');

// 检查属性是否存在
el.hasAttribute('data-id');  // true/false

// 获取所有属性
el.attributes;  // NamedNodeMap

data属性

JavaScript
const el = document.querySelector('.box');

// dataset API
el.dataset.id = '123';
el.dataset.name = '张三';

console.log(el.dataset.id);    // '123'
console.log(el.dataset.name);  // '张三'

// HTML: data-id="123" data-name="张三"

innerHTML/outerHTML

innerHTML

JavaScript
const el = document.querySelector('.container');

// 设置内容(解析HTML)
el.innerHTML = '<div class="item">内容</div>';

// 获取内容
console.log(el.innerHTML);

// 清空内容
el.innerHTML = '';

outerHTML

JavaScript
const el = document.querySelector('.item');

// 获取(含自身)
console.log(el.outerHTML);  // '<div class="item">内容</div>'

// 替换自身
el.outerHTML = '<span class="new">新内容</span>';

innerHTML安全问题

JavaScript
// 危险:用户输入直接innerHTML
el.innerHTML = userInput;  // XSS风险

// 安全:使用textContent
el.textContent = userInput;

// 或转义后innerHTML
el.innerHTML = escapeHTML(userInput);

textContent vs innerText

text
const el = document.querySelector('.box');

// textContent:获取所有文本(含隐藏)
el.textContent;

// innerText:获取可见文本(受CSS影响)
el.innerText;

// 设置文本
el.textContent = '纯文本';  // 推荐
el.innerText = '纯文本';
特性textContentinnerText
性能更快较慢
隐藏文本包含不包含
CSS影响不受影响受影响
推荐推荐特定场景

要点总结

  1. DocumentFragment:批量操作优化,减少重排
  2. cloneNode(true):深克隆含子节点
  3. insertBefore:精确控制插入位置
  4. innerHTML风险:避免XSS,用textContent
  5. textContent推荐:性能更好,不受CSS影响

📝 发现内容有误?点击此处直接编辑

← 上一篇 CSS样式操作与类管理
下一篇 → DOM遍历与选择器
想查看更多题目和详细解析?
小程序提供完整的题库、模拟考试和详细解析
马上就来

长按或扫描二维码,立即体验

扫码体验小程序
马上就来
使用微信扫描二维码
立即体验完整题库