JavaScript学习笔记(三十七)DOM扩展(一)
Selectors API
- Selectors API(参见W3C网站上的Selectors APl Level 1)是W3C推荐标准,规定了浏览器原生支持的CSS查询API。
- 支持这一特性的所有JavaScript库都会实现一个基本的CSS解析器,然后使用已有的DOM方法搜索文档并匹配目标节点。
- Selectors APILevel1的核心是两个方法:queryselector()和 querySelectorAll()。在兼容浏览器中,Document类型和Element类型的实例上都会暴露这两个方法。
- Selectors API Level 2规范在Element类型上新增了更多方法,比如 matches ()、find()和findAll()。不过,目前还没有浏览器实现或宣称实现find()和findAll()。
querySelector()
- 方法接收CSS选择符参数,返回匹配该模式的第一个后代元素,如果没有匹配项则返回null。
1 | // 取得<body>元素 |
- 在Document上使用querySelector()方法时,会从文档元素开始搜索;在Element 上使用querySelector()方法时,则只会从当前元素的后代中查询。
- 如果选择符有语法错误或碰到不支持的选择符,则querySelector( )方法会抛出错误。
querySelectorAll()
- querySelectorAll()方法跟querySelector()一样,也接收一个用于查询的参数,但它会返回所有匹配的节点,而不止一个。这个方法返回的是一个NodeList的静态实例。
- querySelectorAll()返回的 NodeList 实例一个属性和方法都不缺,但它是一个静态的“快照”,而非“实时”的查询。这样的底层实现避免了使用NodeList对象可能造成的性能问题。
- 返回的NodeList对象可以通过for-of循环、item()方法或中括号语法取得个别元素。
- 如果没有匹配项,则返回空的NodeList实例。
- querySelectorAll()也可以在Document、DocumentFragment和Element类型上使用。
1 | // 取得 ID 为"myDiv"的<div>元素中的所有<em>元素 |
matches()
- matches()方法(在规范草案中称为matchesSelector())接收一个CSS选择符参数,如果元素匹配则该选择符返回true,否则返回false。
- 使用这个方法可以方便地检测某个元素会不会被querySelector()或 querySelectorAll()方法返回。
1 | if (document.body.matches("body.page1")){ |
元素遍历
IE9之前的版本不会把元素间的空格当成空白节点,而其他浏览器则会。这样就导致了childNodes和firstchild等属性上的差异。为了弥补这个差异,同时不影响DOM规范,W3C通过新的ElementTraversal规范定义了一组新属性。
Element Traversal API 为 DOM 元素添加了 5 个属性:
- childElementCount:返回子元素数量(不包含文本节点和注释);
- firstElementChild:指向第一个Element类型的子元素(Element版firstChild);
- lastElementChild:指向最后一个 Element类型的子元素(Element版lastchild);
- previousElementSibling:指向前一个Element类型的同胞元素(Element版previoussibling);
- nextElementsibling:指向后一个Element类型的同胞元素(Element 版nextsibling )。
以下是跨浏览器方式遍历特定元素的所有子元素的写法:
1
2
3
4
5
6
7
8
9
10
11
12
13let parentElement = document.getElementById('parent');
let currentChildNode = parentElement.firstChild;
// 没有子元素,firstChild 返回 null,跳过循环
while (currentChildNode) {
if (currentChildNode.nodeType === 1) {
// 如果有元素节点,则做相应处理
processChild(currentChildNode);
}
if (currentChildNode === parentElement.lastChild) {
break;
}
currentChildNode = currentChildNode.nextSibling;
}使用Element Traversal属性之后,以上代码可以简化如下:
1
2
3
4
5
6
7
8
9
10
11let parentElement = document.getElementById('parent');
let currentChildElement = parentElement.firstElementChild;
// 没有子元素,firstElementChild 返回 null,跳过循环
while (currentChildElement) {
// 这就是元素节点,做相应处理
processChild(currentChildElement);
if (currentChildElement === parentElement. lastElementChild) {
break;
}
currentChildElement = currentChildElement.nextElementSibling;
}
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 姚永坤的小窝!
评论