DOM(文档对象模型)是浏览器提供的核心 API 之一,用于将 HTML 文档转换为可操作的对象树结构。其核心设计遵循树形结构,每个节点都继承自Node
接口,主要分为以下类型:
1. 基础节点类型
document
全局对象访问()2. 特殊节点类型
// 创建节点示例
const div = document.createElement('div');
const text = document.createTextNode('Hello DOM');
div.appendChild(text);
DOM 树导航属性:
const parent = element.parentNode;
const firstChild = element.firstChild;
const nextSibling = element.nextSibling;
节点增删改查:
// 插入节点
parent.appendChild(newNode);
parent.insertBefore(newNode, referenceNode);
// 删除节点
parent.removeChild(node);
// 复制节点
const clone = node.cloneNode(true); // 深拷贝
属性与特性的区别:
// Attribute操作
element.setAttribute('class', 'active');
const className = element.getAttribute('class');
// Property操作
element.className = 'active';
性能对比:
方法类型 | 示例代码 | 性能等级 |
---|---|---|
ID 查找 | getElementById('main') |
★★★★★ |
标签名查找 | getElementsByTagName('div') |
★★★★☆ |
类名查找 | getElementsByClassName('box') |
★★★★☆ |
CSS 选择器查找 | querySelector('.active') |
★★★☆☆ |
动态集合特性:
const elements = document.getElementsByClassName('item');
console.log(elements.length); // 初始数量
document.body.appendChild(createElement('div.className="item"'));
console.log(elements.length); // 自动更新
递归遍历实现:
function traverse(node) {
if (node.nodeType === Node.ELEMENT_NODE) {
console.log(node.tagName);
}
node.childNodes.forEach(child => traverse(child));
}
traverse(document.body);
迭代器 API:
const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_ELEMENT);
while (node = walker.nextNode()) {
console.log(node.tagName);
}
创建 Range:
const range = new Range();
range.setStart(textNode, 5); // 起始位置
range.setEnd(textNode, 10); // 结束位置
内容操作:
// 提取内容
const fragment = range.extractContents();
// 插入内容
range.insertNode(document.createTextNode('Replaced'));
// 使用DocumentFragment
const fragment = document.createDocumentFragment();
for (let i = 0; i < 1000; i++) {
const li = document.createElement('li');
fragment.appendChild(li);
}
ul.appendChild(fragment);
ul.addEventListener('click', (e) => {
if (e.target.tagName === 'LI') {
handleClick(e.target);
}
});
Q1:为什么建议使用getElementById
而非querySelector
?
getElementById
直接访问内部哈希表,时间复杂度 O (1)Q2:如何高效获取所有元素?
// 性能最优方案
const allElements = document.getElementsByTagName('*');
Q3:如何避免内存泄漏?
// 移除事件监听
element.removeEventListener('click', handler);
// 清空引用
parent.removeChild(node);
node = null;
DOM API 是前端开发的基石,掌握节点类型、遍历策略和高效操作方法对性能优化至关重要。通过合理使用DocumentFragment
、事件委托和选择器优化,开发者可以显著提升页面交互体验。下一讲将深入探讨 HTML 链接标签的高级应用与最佳实践。