JavaScript高级程序设计笔记 14
第14章 DOM(文档对象模型)
1. DOM 概述
- DOM 是 HTML/XML 文档的编程接口,将文档表示为节点树。
- 级别:DOM Level 1(核心+HTML)、Level 2(样式、事件、遍历)、Level 3(加载与保存、验证)。
2. 节点层级
2.1 Node 类型(基类)
- 所有节点类型均继承自
Node。 - 常用常量:
Node.ELEMENT_NODE(1)、TEXT_NODE(3)、DOCUMENT_NODE(9)。 - 节点属性:
nodeName、nodeValue(元素节点无意义,文本节点存文本)。parentNode、childNodes(NodeList,类数组且动态实时)、firstChild、lastChild、previousSibling、nextSibling。ownerDocument(指向所属文档)。
- 节点方法:
appendChild()、insertBefore()、replaceChild()、removeChild()(均需父节点调用)。cloneNode(deep)(深克隆包含子节点)。normalize()(合并相邻文本节点)。
2.2 Document 类型
document对象(浏览器中为 HTMLDocument 实例),表示整个文档。- 属性:
documentElement(<html>)、body(<body>)、title、URL、domain、referrer。 - 获取元素:
getElementById(id)(最常用,ID 必须唯一)。getElementsByTagName(tag)(返回动态 HTMLCollection)。getElementsByName(name)。querySelector(selector)/querySelectorAll(selector)(返回静态 NodeList,推荐)。
- 特殊集合:
anchors、forms、images、links等。 - 写入文档:
write()、writeln()(尽量少用,会阻塞解析)。
2.3 Element 类型
- 表示 HTML/XML 元素。
- 属性:
id、className、classList(方便操作类名)。attributes(NamedNodeMap,元素的属性集合)。
- 方法:
- 获取/设置属性:
getAttribute()、setAttribute()、removeAttribute()。 - 属性访问:直接用
.property访问标准属性(如div.id),自定义属性用getAttribute或dataset。
- 获取/设置属性:
dataset:访问data-*属性(如element.dataset.userId对应data-user-id)。- 创建元素:
document.createElement(tagName)。
2.4 Text 类型
- 表示文本节点,
nodeValue或data存储文本。 - 方法:
appendData()、deleteData()、insertData()、replaceData()、splitText()。 - 创建文本节点:
document.createTextNode(text)。
2.5 Comment 类型(注释节点)
nodeType === 8,可用document.createComment(text)创建。
2.6 CDATASection、DocumentType 等(较少用)
3. DOM 操作
3.1 创建与插入节点
let div = document.createElement('div');
div.className = 'box';
div.innerHTML = '<span>Hello</span>';
document.body.appendChild(div);
3.2 删除与替换
parent.removeChild(child);
parent.replaceChild(newNode, oldNode);
3.3 性能优化(减少重排/重绘)
- 使用
document.createDocumentFragment()批量添加节点。 - 先操作脱离文档的节点,最后一次性插入。
- 避免频繁读取布局属性(如
offsetHeight)。
4. 选择符 API
querySelector(selector):返回第一个匹配的元素(无则 null)。querySelectorAll(selector):返回静态 NodeList(快照)。matches(selector):检测元素是否匹配选择符(element.matches或msMatchesSelector)。
5. 元素遍历(Element Traversal API)
- 只遍历元素节点,忽略文本/注释节点:
parentElement、children(HTMLCollection)、firstElementChild、lastElementChild、previousElementSibling、nextElementSibling。
6. HTML5 新增 DOM 扩展
6.1 类名操作
classList:add()、remove()、toggle()、contains()(极大便利)。
6.2 焦点管理
document.activeElement:当前获得焦点的元素。element.focus()、element.blur()。
6.3 自定义数据属性
dataset对象,如<div data-id="123">→div.dataset.id === '123'。
6.4 插入标记
innerHTML/outerHTML/insertAdjacentHTML(position, html)。innerHTML性能与安全问题:避免直接拼接用户输入(XSS)。
6.5 scrollIntoView()
- 滚动元素到可视区域:
element.scrollIntoView({ behavior: 'smooth' })。
7. 样式与类
7.1 内联样式
element.style.property(驼峰命名,如backgroundColor)。element.style.cssText批量设置。
7.2 计算样式
getComputedStyle(element, pseudo):返回只读对象,包含最终样式。
8. 节点遍历(TreeWalker / NodeIterator)
document.createNodeIterator(root, whatToShow, filter):遍历节点。document.createTreeWalker:增加移动方法(parentNode、firstChild等)。
9. 常见面试题速查
-
DOM 节点类型有哪几种?如何判断?
→ 元素(1)、属性(2)、文本(3)、文档(9)、注释(8) 等;通过nodeType。 -
querySelectorAll返回的是动态还是静态集合?
→ 静态 NodeList(快照),不随 DOM 变化更新。 -
getElementsByTagName与querySelectorAll的区别?
→ 前者返回动态 HTMLCollection,后者返回静态 NodeList;后者支持任意 CSS 选择符。 -
如何创建文档片段?有何作用?
→createDocumentFragment(),用于批量操作节点,避免多次重绘。 -
innerHTML的安全风险?如何防范?
→ 可能注入 XSS;应对用户输入进行转义或使用textContent替代。 -
classList相比className的优势?
→ 提供add、remove、toggle等方便操作,不会覆盖已有类。 -
如何获取元素的最终样式?
→getComputedStyle(element)。 -
scrollIntoView的常用参数?
→{ behavior: 'smooth', block: 'start' }等。 -
childNodes和children的区别?
→childNodes包含所有节点(文本、注释等),children只包含元素节点。 -
如何遍历 DOM 树?
→ 递归children或使用TreeWalker。

浙公网安备 33010602011771号