6.2.2 往来于文档树间 -节点遍历-
目前为止介绍的getXxxxx/queryXxxxx方法,都是使用精确定位来获取特定节点的方法。但是,从文档整体中逐个检索目标元素会有很多徒劳,这也是造成性能低下的原因。
因此在DOM中,也可以将某个节点作为基点,根据相对的位置关系获取节点。在树状的节点之间,沿着枝进行搜索的动作称为节点遍历。具体使用下图所示的属性。
【288页】
文档整理
祖先节点
父节点
兄节点
当前节点
弟节点
兄元素
弟元素
开头的子节点
最后的子节点
开头的子元素
最后的子元素
(所有的子节点)
●使用相对关系获取节点的属性
和getXxxxx/queryXxxxx方法相比,虽然代码变得冗长了,但是更加灵活,所以通常在使用getXxxxx/queryXxxxx方法获取特定的元素之后,使用节点遍历获取附近的节点。
■节点遍历的基础
那么,我们来看下具体的例子吧。例如下面是获取<select id="food">
元素下面的<option>
元素并罗列其value属性的例子。
●清单 6-07 child_nodes.html(上)/child_node.js(下)
最喜欢的食物是?:
"拉面"拉面
"饺子"饺子
"烤肉"烤肉
【289页】
"发送"
获取<select id="food">
// 获取<select>
元素中的子节点
// 依次获取子节点
// 只有当子节点是元素节点时才将其值输出到日志中
拉面
饺子
烤肉
childNodes属性的功能是获取元素的直接子节点(①)。childNodes属性和getElementsByName/querySelectorAll等方法相同,是将节点列表作为NodeList对象返回的。但是,请注意,列表中的节点「不只是元素」。下面是表示childNodes.html的文档结构的树状图。
NodeList中的不只是元素
最喜欢的食物是?:
拉面
饺子
烤肉
是空白节点。属性省略
●child_nodes.html的文档树
【290页】
像这样,标签间的换行和空格视为文本节点。因此,childNodes属性也可能获取到元素节点和文本节点。
像这次这样只获取<option>
元素时,需要判断取出的节点是否是元素节点。
nodeType属性的作用是判断节点的种类(②)。下面是nodeType属性的返回值。
返回值 | 概要 |
---|---|
1 | 元素节点 |
2 | 属性节点 |
3 | 文本节点 |
4 | CDATA区域(<![CDATA[~]]>) |
5 | 实体引用节点 |
6 | 实体声明节点 |
7 | 处理命令节点 |
8 | 注释节点 |
9 | 文档节点 |
10 | 文档类型声明节点 |
11 | 文档的片段(Fragment) |
12 | 符号名称 |
●节点的种类(nodeType属性的返回值)
在这个例子中,只有当nodeType属性为1(元素节点)时,才获取这个值(value属性)。
■其他获取子元素列表的方法
虽然清单6-07中使用的是childNodes属性,但其实还有像下面这样的其他途径。根据当时的上下文来决定使用哪一个,这里先理解「1个实现有各种各样的方法」,扩充自己的选择范围。
(1)firstChild/nextSibling属性
使用firstChild/nextSibling属性,可以像下面这样改写(改写的是清单6-07的粗体字部分)。
●清单6-08 first_child.js(只是替换的部分)
// 获取
<select>
元素的第一个子节点
// 在有子节点的期间内循环
// 获取下一饿子节点(弟节点)
在这个例子中,从<select>
元素中第一个子节点开始,依次获取之后的兄弟节点(直到后面没有为止)。使用lastChild/previousSibling属性也是基本相同的,所以有余力的读者可以尝试一下。
【291页】
(2)firstElementChild/nextElementSibling属性
firstElementChild属性返回下面的子元素,nextElementSibling属性获取之后的兄弟元素。和firstChild/nextSibling属性不同,返回值是Element(元素)对象,所以不需要使用nodeType属性判断。
和之前相同,下面是替换清单6-07的粗体字部分。
●清单6-09 first_child_element.js
// 获取
<select>
元素的第一个子节点
// 在有子节点的期间内循环
和①相同,lastElementChild/previousElementSibling属性可以从末尾的子元素开始依次访问。