JavaScript教程:深入理解DOM导航
前言
DOM(文档对象模型)是JavaScript与网页交互的核心接口。理解如何高效地遍历DOM树是每个前端开发者必备的技能。本文将全面讲解DOM导航的各种方法和技巧,帮助你掌握元素间的关系和访问方式。
DOM导航基础
DOM将HTML文档表示为节点树,所有操作都始于document
对象。这是访问DOM的入口点,从这里我们可以到达任何节点。
顶层节点访问
HTML文档中最顶层的几个节点可以直接通过document属性访问:
- document.documentElement:对应
<html>
元素 - document.body:对应
<body>
元素 - document.head:对应
<head>
元素
console.log(document.documentElement); // <html>元素
console.log(document.body); // <body>元素
console.log(document.head); // <head>元素
重要注意事项
当脚本位于<head>
中时,document.body
可能为null
,因为浏览器尚未解析到<body>
标签。这是一个常见的陷阱:
<head>
<script>
console.log(document.body); // null,因为<body>还未加载
</script>
</head>
<body>
<!-- 页面内容 -->
</body>
子节点导航
理解DOM中的两个关键术语:
- 子节点(children):直接嵌套在元素中的节点
- 后代节点(descendants):所有嵌套在元素中的节点,包括子节点、子节点的子节点等
访问子节点
childNodes
集合提供了元素的所有子节点,包括文本节点和注释节点:
for (let node of document.body.childNodes) {
console.log(node);
}
快捷属性
- firstChild:第一个子节点
- lastChild:最后一个子节点
- hasChildNodes():检查是否有子节点
// 以下表达式总是成立
elem.childNodes[0] === elem.firstChild;
elem.childNodes[elem.childNodes.length - 1] === elem.lastChild;
DOM集合的特性
childNodes
看起来像数组,但实际上是一个类数组的可迭代集合,具有以下特点:
- 可以使用
for..of
遍历 - 没有数组方法(如filter、map等),但可以通过
Array.from()
转换 - 是**实时(live)**的,会反映DOM的当前状态
- 不要使用
for..in
遍历,因为它会遍历所有可枚举属性
// 转换为真实数组以使用数组方法
const childArray = Array.from(document.body.childNodes);
childArray.filter(node => node.nodeType === 1); // 筛选出元素节点
兄弟节点和父节点
兄弟节点访问
- nextSibling:下一个兄弟节点
- previousSibling:前一个兄弟节点
- parentNode:父节点
// <head>和<body>是兄弟节点
console.log(document.head.nextSibling); // <body>
console.log(document.body.previousSibling); // <head>
console.log(document.body.parentNode); // <html>
仅元素导航
有时我们只关心元素节点(标签节点),忽略文本和注释节点。DOM提供了专门的属性:
- children:只包含元素子节点
- firstElementChild/lastElementChild:第一个/最后一个元素子节点
- previousElementSibling/nextElementSibling:相邻元素节点
- parentElement:父元素节点
// 只遍历元素子节点
for (let elem of document.body.children) {
console.log(elem.tagName); // 只输出元素标签名
}
parentElement vs parentNode
parentElement
和parentNode
通常相同,但有一个例外:
console.log(document.documentElement.parentNode); // document对象
console.log(document.documentElement.parentElement); // null
因为document
不是元素节点,所以parentElement
返回null
。
表格的特殊导航
表格元素提供了额外的便捷属性:
<table>
元素
- rows:所有
<tr>
元素的集合 - caption/tHead/tFoot:对应
<caption>
、<thead>
、<tfoot>
元素 - tBodies:所有
<tbody>
元素的集合
<tbody>
元素
- rows:包含的
<tr>
元素集合
<tr>
元素
- cells:包含的
<td>
/<th>
元素集合 - sectionRowIndex:在
<thead>
/<tbody>
/<tfoot>
中的索引 - rowIndex:在整表中的行索引
<td>
/<th>
元素
- cellIndex:在所在行中的单元格索引
// 获取表格中第一行第二列的单元格
let td = table.rows[0].cells[1];
td.style.backgroundColor = "red";
总结
DOM导航分为两大类方法:
-
适用于所有节点:
- parentNode
- childNodes
- firstChild/lastChild
- previousSibling/nextSibling
-
仅适用于元素节点:
- parentElement
- children
- firstElementChild/lastElementChild
- previousElementSibling/nextElementSibling
某些特定类型的DOM元素(如表格)还提供了额外的导航属性和集合,使访问其内容更加方便。
掌握这些导航方法,你就能高效地在DOM树中移动,精确地定位和操作任何元素。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考