JavaScript高级程序设计笔记 15
第15章 DOM 扩展
1. 概述
- DOM 扩展的两个主要标准:Selectors API 与 HTML5(另有较小的 Element Traversal 规范)。
- 目的:将实践中已广泛使用的专有扩展标准化。
2. Selectors API(选择符 API)
- 核心:让浏览器原生支持 CSS 查询,性能远超 JavaScript 实现的解析器。
- Level 1 的两个核心方法(Document 和 Element 类型上均可用):
2.1 querySelector()
- 接收一个 CSS 选择符,返回匹配的第一个元素,没有则返回 null。
- 在 Document 上调用从文档元素开始搜索;在 Element 上调用则从当前元素的后代中搜索。
- 示例:
document.querySelector('#myDiv'); element.querySelector('.selected');
2.2 querySelectorAll()
- 接收一个 CSS 选择符,返回所有匹配的节点(NodeList 静态实例,是“快照”而非“实时”查询)。
- 示例:
document.querySelectorAll('p strong');
2.3 matches() / matchesSelector()
- Selectors API Level 2 规范新增,在 Element 类型上可用。
- 接收一个 CSS 选择符,如果元素匹配则该选择符返回 true,否则返回 false。
- 可用于检测元素是否会匹配 querySelector() 方法的查询条件。
3. 元素遍历(Element Traversal API)
- API:为 DOM 元素添加了 5 个属性,只遍历元素节点,忽略文本节点和注释节点。
childElementCount:返回子元素数量。firstElementChild/lastElementChild:指向第一个 / 最后一个子元素。previousElementSibling/nextElementSibling:指向前一个 / 后一个同胞元素。
4. HTML5 DOM 扩展
- 定义了浏览器应当支持的 DOM 扩展。
4.1 CSS 类扩展
- getElementsByClassName() 方法:接收一个或多个类名字符串,返回包含指定类的所有元素的 NodeList。
- classList 属性:所有元素都有的属性,是 DOMTokenList 的实例,提供了便捷的类名操作方法。
add(value):添加类名。contains(value):检查类名是否存在。remove(value):移除类名。toggle(value):如果存在则删除,否则添加。
4.2 焦点管理
document.activeElement:始终引用当前获得焦点的 DOM 元素。document.hasFocus():返回布尔值,表示文档是否拥有焦点。
4.3 HTMLDocument 扩展
- readyState 属性:
loading:文档正在加载。complete:文档加载完成。
- compatMode 属性:告诉开发者浏览器处于什么渲染模式。
CSS1Compat:标准模式。BackCompat:混杂模式。
- head 属性:
document.head直接指向文档的<head>元素。
4.4 字符集属性
document.characterSet属性表示文档实际使用的字符集,如'UTF-16'。
4.5 自定义数据属性
- 前缀为
data-的自定义属性(如data-id="123")。 - 通过元素的
dataset属性访问,dataset属性是一个 DOMStringMap 实例,包含一组键值对。
4.6 插入标记
- innerHTML 属性:
- 读取时返回元素所有后代的 HTML 字符串。
- 写入时根据提供的字符串创建新的 DOM 子树,并替换原有子节点。
- outerHTML 属性:
- 读取时返回调用它的元素及所有后代元素的 HTML 字符串。
- 写入时调用它的元素会被传入的 HTML 字符串生成的 DOM 子树取代。
- insertAdjacentHTML() / insertAdjacentText() 方法:
- 接收两个参数:插入位置和要插入的 HTML 或文本。
- 位置参数:
'beforebegin','afterbegin','beforeend','afterend'。
- 内存与性能问题:
- 使用 innerHTML 和 outerHTML 时,需要手动删除被替换元素上的事件处理程序和 JavaScript 对象属性,避免内存泄漏。
- 批量操作时推荐先构建一个独立的 DOM 树(如使用
createDocumentFragment()),最后再一次性插入,以减少浏览器重排(Reflow)和重绘(Repaint)。
4.7 scrollIntoView() 方法
- 存在于所有 HTML 元素上,可以滚动浏览器窗口使元素进入视口。
5. 专有扩展
- 尽管 Selectors API 和 HTML5 两个规范已涵盖大量 DOM 扩展,但一些浏览器的专有扩展仍然存在。
- children 属性:与
childNodes类似,但children只包含元素节点,是 HTMLCollection 实例。 - contains() 方法:判断一个节点是不是另一个节点的后代。
6. 常见面试题速查
-
querySelector 和 querySelectorAll 返回的集合是“实时的”还是“静态的”?
→ querySelectorAll 返回一个静态的 NodeList“快照”,不会随文档更新。而 getElementsByClassName 等方法返回的是实时的 HTMLCollection。 -
classList 相比 className 有什么优势?
→ classList 提供了 add、remove、toggle 和 contains 等便捷方法,避免了通过字符串拼接修改类名的繁琐和出错风险。 -
如何安全地使用 innerHTML?
→ 永远不要将用户输入的字符串直接赋值给 innerHTML。在插入任何不可信的字符串之前,必须进行转义(例如,将<转义为<),以防止 XSS 攻击。 -
如何判断一个元素是否匹配某个 CSS 选择器?
→ 使用element.matches(selector)方法。 -
页面加载状态可以通过什么属性判断?
→ 通过document.readyState属性,值为'loading'或'complete'。 -
如何获取
<head>元素?
→ 使用document.head属性。 -
Element Traversal API 解决了什么问题?
→ 解决了空白文本节点可能干扰遍历结果的问题,因为它提供的属性只返回元素节点。 -
什么是 dataset?
→ dataset 是用于访问元素上自定义数据属性(data-*)的接口。

浙公网安备 33010602011771号