HTML DOM 技术文档
1. DOM 基础概念
什么是 DOM
- DOM(Document Object Model)是一种用于表示 HTML 和 XML 文档的编程接口。
- 它将文档结构表示为树状结构,允许开发者通过 JavaScript 动态操作页面内容和样式。
DOM 树结构
- DOM 是一棵树,每个节点代表文档中的一部分:
- 文档节点(Document): 整个 HTML 文档的根节点。
- 元素节点(Element): HTML 元素,如
<div>
或<p>
。 - 文本节点(Text): 元素内部的文本内容。
- 属性节点(Attribute): 元素的属性。
- 注释节点(Comment): HTML 注释。
常见节点类型
- Node.ELEMENT_NODE: 元素节点(1)
- Node.ATTRIBUTE_NODE: 属性节点(2, 不常用)
- Node.TEXT_NODE: 文本节点(3)
- Node.COMMENT_NODE: 注释节点(8)
DOM 接口和对象
Document
: 表示整个 HTML 页面。Element
: 表示一个 HTML 元素。Node
: 所有节点的基类。Event
: 用于处理 DOM 事件。
2. 选择和访问 DOM 元素
选择 DOM 元素的方法
getElementById(id)
- 根据元素的
id
获取唯一的元素。 const element = document.getElementById("myDiv");
getElementsByClassName(className)
- 根据
class
获取元素集合(HTMLCollection)。 const elements = document.getElementsByClassName("myClass");
getElementsByTagName(tagName)
- 根据标签名获取元素集合。
const elements = document.getElementsByTagName("div");
querySelector(selector)
- 根据 CSS 选择器获取第一个匹配的元素。
const element = document.querySelector(".myClass");
querySelectorAll(selector)
- 获取所有匹配选择器的元素(NodeList)。
const elements = document.querySelectorAll("div.myClass");
遍历 DOM 树
- 父节点:
parentNode
- 子节点:
childNodes
,firstChild
,lastChild
- 兄弟节点:
nextSibling
,previousSibling
- 示例:
const parent = document.getElementById("child").parentNode; const children = parent.childNodes; // 包括文本节点
3. 操作 DOM 元素
创建新元素
- 使用
createElement()
创建新元素。 const newDiv = document.createElement("div"); newDiv.textContent = "Hello World!";
添加元素
- 使用
appendChild()
或insertBefore()
将元素插入 DOM 树。document.body.appendChild(newDiv);
删除元素
- 使用
removeChild()
删除子元素。 const parent = document.getElementById("parent");
const child = document.getElementById("child"); parent.removeChild(child);
替换元素
- 使用
replaceChild()
替换元素。 const newElement = document.createElement("p"); parent.replaceChild(newElement, child);
克隆元素
- 使用
cloneNode()
克隆元素。 const clone = newDiv.cloneNode(true); // true 表示深拷贝
4. 修改 DOM 元素
修改元素内容
innerHTML
:包含 HTML 标签的内容。textContent
:仅包含文本内容。element.innerHTML = "<strong>Hello!</strong>"; element.textContent = "Hello!";
修改元素属性
setAttribute()
和removeAttribute()
。element.setAttribute("class", "newClass"); element.removeAttribute("class");
修改元素样式
- 使用
style
属性直接设置样式。 element.style.color = "red"; element.style.fontSize = "20px";
- 使用
classList
添加、删除、切换类。 element.classList.add("newClass");
element.classList.remove("oldClass"); element.classList.toggle("toggleClass");
5. DOM 事件
常见事件类型
- 鼠标事件:
click
,dblclick
,mousemove
,mouseover
- 键盘事件:
keydown
,keyup
- 其他事件:
load
,resize
,scroll
添加事件监听器
- 使用
addEventListener()
。 element.addEventListener("click", () => { console.log("Element clicked!"); });
事件冒泡与捕获
- 冒泡: 从目标元素向上传播到父元素。
- 捕获: 从根节点向目标元素传播。
element.addEventListener( "click", () => { console.log("Clicked in capturing phase!"); }, true // 捕获阶段);
事件对象
- 使用事件对象访问事件信息。
element.addEventListener("click", (event) => { console.log(event.target); // 被点击的目标});
自定义事件
- 使用
CustomEvent
创建和触发事件。 const customEvent = new CustomEvent("myEvent", { detail: { key: "value" } }); element.dispatchEvent(customEvent);
6. DOM 操作性能优化
文档片段
- 使用
DocumentFragment
批量插入多个节点,提高性能。 const fragment = document.createDocumentFragment(); for (let i = 0; i < 1000; i++) { const div = document.createElement("div"); div.textContent = `Item ${i}`; fragment.appendChild(div); } document.body.appendChild(fragment);
减少重绘和重排
- 通过修改样式类、使用离线节点操作等减少性能开销。
7. 高级 DOM 操作
Shadow DOM
- 隔离样式和 DOM 结构,适用于 Web Components。
const shadowRoot = element.attachShadow({ mode: "open" }); shadowRoot.innerHTML = "<p>Shadow DOM content</p>";
DOM 变动观察器
- 使用
MutationObserver
监听 DOM 的变动。 const observer = new MutationObserver((mutations) => { mutations.forEach((mutation) => { console.log(mutation.type); }); }); observer.observe(document.body, { childList: true, subtree: true });
8. DOM 与安全
防范 XSS
- 不直接插入用户输入到
innerHTML
。 - 使用
textContent
替代。
安全工具
- 使用安全库(如 DOMPurify)过滤用户输入。
9. 调试和性能监控
- 使用浏览器开发者工具查看 DOM 树和事件绑定。
- 使用
Performance
面板分析重排和重绘。