JavaScript DOM 導航
在本教程中,你將學習如何在 JavaScript 中的 DOM 節點之間導航。
在 DOM 節點之間導航
在前面的章節中,你已經學習瞭如何在網頁上選擇單個元素。但是在很多情況下,你需要訪問子元素、父元素或祖先元素。請參閱 JavaScript DOM 節點 一章,瞭解 DOM 樹中節點之間的邏輯關係。
DOM 節點提供了幾個屬性和方法,允許你導航或遍歷 DOM 的樹結構並輕鬆進行更改。在下一節中,我們將學習如何使用 JavaScript 在 DOM 樹中向上,向下和橫向導航。
訪問子節點
你可以使用 DOM 節點的 firstChild
和 lastChild
屬性分別訪問節點的第一個和最後一個直接子節點。如果節點沒有任何子元素,則返回 null
。
<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>
<script>
var main = document.getElementById("main");
console.log(main.firstChild.nodeName); // Prints: #text
var hint = document.getElementById("hint");
console.log(hint.firstChild.nodeName); // Prints: SPAN
</script>
注意: nodeName
是一個只讀屬性,它將當前節點的名稱作為字串返回。例如,它返回元素節點, #text
文字節點, #comment
註釋節點, #document
文件節點等的標記名稱。
如果你注意到上面的示例,則主 DIV 元素的第一個子節點的 nodeName
返回 #text
而不是 H1
。因為空格、製表符、換行符等空格是有效字元,它們形成 #text
節點併成為 DOM 樹的一部分。因此,由於 <div>
標記在 <h1>
標記之前包含換行符,因此它將建立一個 #text
節點。
要避免 firstChild
和 lastChild
返回 #text
或 #comment
節點的問題,你可以使用 firstElementChild
和 lastElementChild
屬性分別僅返回第一個和最後一個元素節點。但是,它不適用於 IE 9 及更早版本。
<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>
<script>
var main = document.getElementById("main");
alert(main.firstElementChild.nodeName); // Outputs: H1
main.firstElementChild.style.color = "red";
var hint = document.getElementById("hint");
alert(hint.firstElementChild.nodeName); // Outputs: SPAN
hint.firstElementChild.style.color = "blue";
</script>
類似地,你可以使用 childNodes
屬性訪問給定元素的所有子節點,其中第一個子節點被指定為索引 0
.這是一個示例:
<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>
<script>
var main = document.getElementById("main");
// First check that the element has child nodes
if(main.hasChildNodes()) {
var nodes = main.childNodes;
// Loop through node list and display node name
for(var i = 0; i < nodes.length; i++) {
alert(nodes[i].nodeName);
}
}
</script>
childNodes
返回所有子節點,包括像文字和註釋節點非元素節點。要僅獲取元素的集合,請改用 children
屬性。
<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>
<script>
var main = document.getElementById("main");
// First check that the element has child nodes
if(main.hasChildNodes()) {
var nodes = main.children;
// Loop through node list and display node name
for(var i = 0; i < nodes.length; i++) {
alert(nodes[i].nodeName);
}
}
</script>
訪問父節點
你可以使用 parentNode
屬性訪問 DOM 樹中指定節點的父節點。
文件節點的 parentNode
將始終返回 null
,因為它沒有父節點。
<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>
<script>
var hint = document.getElementById("hint");
alert(hint.parentNode.nodeName); // Outputs: DIV
alert(document.documentElement.parentNode.nodeName); // Outputs: #document
alert(document.parentNode); // Outputs: null
</script>
提示: 最頂層的 DOM 樹節點可以作為 document
屬性直接訪問。例如,可以使用 document.documentElement
屬性訪問 <html>
元素,可以使用 document.head
屬性訪問 <head>
元素,並且可以使用 document.body
屬性訪問 <body>
元素。
但是,如果你只想獲取元素節點,可以使用 parentElement
,如下所示:
<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>
<script>
var hint = document.getElementById("hint");
alert(hint.parentNode.nodeName); // Outputs: DIV
hint.parentNode.style.backgroundColor = "yellow";
</script>
訪問兄弟節點
你可以使用 previousSibling
和 nextSibling
屬性分別訪問 DOM 樹中的上一個和下一個節點。這是一個例子:
<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p><hr>
</div>
<script>
var title = document.getElementById("title");
alert(title.previousSibling.nodeName); // Outputs: #text
var hint = document.getElementById("hint");
alert(hint.nextSibling.nodeName); // Outputs: HR
</script>
或者,你可以使用 previousElementSibling
和 nextElementSibling
來獲取前一個和下一個兄弟元素,跳過任何空白文字節點。如果沒有這樣的兄弟節點,所有這些屬性都會返回 null
。這是一個例子:
<div id="main">
<h1 id="title">My Heading</h1>
<p id="hint"><span>This is some text.</span></p>
</div>
<script>
var hint = document.getElementById("hint");
alert(hint.previousElementSibling.nodeName); // Outputs: H1
alert(hint.previousElementSibling.textContent); // Outputs: My Heading
var title = document.getElementById("title");
alert(title.nextElementSibling.nodeName); // Outputs: P
alert(title.nextElementSibling.textContent); // Outputs: This is some text.
</script>
textContent
屬性表示節點及其所有後代的文字內容。請參閱 JavaScript DOM 操作 章節以瞭解有關它的更多資訊。
DOM 節點的型別
DOM 樹由不同型別的節點組成,例如元素、文字、註釋等。
每個節點都有一個 nodeType
屬性,你可以使用該屬性來找出你正在處理的節點型別。下表列出了最重要的節點型別:
不變 | 值 | 描述 |
---|---|---|
ELEMENT_NODE |
1 | 一個元素節點,如 <p> 或 <img> 。 |
TEXT_NODE |
3 | 元素的實際文字。 |
COMMENT_NODE |
8 | 評論節點即 <!-- some comment --> |
DOCUMENT_NODE |
9 | 文件節點,即 <html> 元素的父節點。 |
DOCUMENT_TYPE_NODE |
10 | 文件型別節點,例如 <!DOCTYPE html> 用於 HTML5 文件。 |