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 面板分析重排和重绘。