遍历 DOM 对象及子节点与父节点访问
DOM 让我们可以对元素和它们中的内容做任何事,对 DOM 的所有操作都是以 document 对象开始。
最顶层的树节点获取<html>标签,使用 document.documentElement。
获取<body>标签,使用 document.body,document.body是使用最多的节点。
更多节点还有<head> = document.head。
如果某个节点不存在,访问时会得到Null, document.body 的值可能是 null,在 DOM 的世界中,null 就意味着“不存在”,下面例子中就没有body节点:
<html> <head> <script> alert( "body节点: " + document.body ); // <body>不存在 </script> </html>
如果一个脚本是在 <head> 中,那么脚本是访问不到 document.body 元素的,因为浏览器还没有读到它。
<html> <head> <script> alert( "在HEAD中读取body: " + document.body ); // null,这里目前还没有 <body> </script> </head> <body> <script> alert( "BODY中: " + document.body ); // HTMLBodyElement,现在存在了 </script> </body> </html>
子节点:childNodes,firstChild,lastChild
从现在开始,我们将使用下面这两个术语:
子节点(或者叫作子) — 对应的是直系的子元素。换句话说,它们被完全嵌套在给定的元素中。例如,<head> 和 <body> 就是 <html> 元素的子元素。
子孙元素 — 嵌套在给定元素中的所有元素,包括子元素,以及子元素的子元素等。
例如,这里 <body> 有子元素 <p> 和 <ul> 节点:
<html> <body> <p>认识子节点</p> <ul> <li> <b>这是li中的一个粗体字</b> </li> </ul> </body> </html>
<body> 元素的子孙元素不仅包含直接的子元素 <p> 和 <ul>,还包含像 <li>(<ul> 的子元素)和 <b>(<li> 的子元素)这样的元素 — 整个子树。
你可以看作<p>和<ul>是兄弟,都是<body>的儿子,<li>是<ul>的儿子,是<body>的孙子,通过爷爷就能够找到孙子。
childNodes 集合可以列出了所有子节点,包括文本节点。
下面这个例子显示了 document.body 的所有子元素:
<html> <body> <div>Begin</div> <ul> <li>Information</li> </ul> <div>End</div> <script> for (let i = 0; i < document.body.childNodes.length; i++) { alert( document.body.childNodes[i] ); } </script> </body> </html>
弹出的窗口中都是提示object text 、object HTMLUListElement等字样,这是因为所有节点都是一个对象object。
firstChild 和 lastChild 属性可以快速的访问第一个和最后一个子元素。
document.body.firstChild //获得body的第一个子元素 document.body.lastChild //获得body的第最后一个子元素
这里还有一个特别的函数 elem.hasChildNodes() 用于检查节点是否有子节点。
DOM 集合
childNodes 看起来就像一个数组。但实际上它并不是一个数组,而是一个 集合。
我们可以使用 for..of 来迭代它:
for (let node of document.body.childNodes) { alert(node); // 显示集合中的所有节点 }
DOM 集合是只读的,他能够读到所有元素的相关信息,并且是实时的,当一个元素改变,DOM会立刻改变。
兄弟节点和父节点
兄弟节点(Sibling) 是指有同一个父节点的节点。
例如,<head> 和 <body> 就是兄弟节点:
<html> <head>...</head><body>...</body> </html>
<body> 可以说是 <head> 的“下一个”或者“右边”兄弟节点。
<head> 可以说是 <body> 的“前一个”或者“左边”兄弟节点。
下一个兄弟节点在 nextSibling 属性中,上一个是在 previousSibling 属性中。
可以通过 parentNode 来访问父节点。
例如:
<scrit> // <body> 的父节点是 <html> alert( document.body.parentNode === document.documentElement ); // true // <head> 的后一个是 <body> alert( document.head.nextSibling ); // HTMLBodyElement // <body> 的前一个是 <head> alert( document.body.previousSibling ); // HTMLHeadElement // 利用head节点来获取兄弟节点body,并且设置body的背景为红色 document.head.nextSibling.style.background = 'red'; // 利用head节点来获取兄弟节点body,并且获取body内的html代码 let savehtml = document.head.nextSibling.innerHTML; </script>