深入理解 DOM 中的 .parentNode 和 .children 屬性

更新日期: 2024 年 9 月 14 日

在 DOM(Document Object Model) 結構中,每一個網頁元素都是一個節點(Node)。

而這些節點彼此之間有著家族般的關係:有父母、有孩子,還有兄弟姐妹。

今天,我們將聚焦於兩個非常實用的屬性: .parentNode 和 .children。這兩個屬性讓我們能夠在這個龐大家族中輕鬆地找到我們需要的「親人」。

.parentNode 屬性介紹

用途

簡單來說,.parentNode 就像是一個指示牌,指向當前元素的直接父節點。

這個父節點可以是另一個元素,也可以是更高一級的文檔節點:比如 <body> 或 <html>。

這種關係很像現實生活中的親子關係:每個孩子都有父母,而在 DOM 樹中,每個元素都有它的父節點。

想象一下你正在一棵巨大的樹下尋找特定的樹枝,.parentNode 就是那個幫助你追蹤到樹枝連接的主幹的工具。

在 DOM 樹中,當你選中一個元素並想要找到它的直接來源時,使用 .parentNode 屬性會直接將你帶到這個元素的父節點。

限制

雖然 .parentNode 非常有用,但它也有其限制。

最主要的限制就是它只能返回一個元素——當前元素的直接父節點。

代碼範例

HTML 結構

<div id="parent">
    <p id="child">你好,世界!</p>
</div>

JavaScript 結構

// 示例 1:有父元素的節點

var childElement = document.getElementById("child");
var parentElement = childElement.parentNode;

console.log(parentElement.id); 

// 輸出: 
// "parent"

在這個例子中,parentNode 屬性用於獲取 id 為 child 的 <p> 元素的父元素,也就是 id 為 parent 的 <div> 元素。

// 示例 2:無父元素的節點

var detachedElement = document.createElement("div");

console.log(detachedElement.parentNode); 

// 輸出: 
// null

在這個例子中,創建了一個新的 <div> 元素,但由於它沒有被添加到 DOM 中,所以它的 .parentNode 屬性返回 null。

.children 屬性介紹

用途

.children 屬性,就像是一個家長的手機聯絡人列表,裡面存儲著他們所有親生子女的資訊。

在DOM中,當你選中一個元素並想要了解它的直接子元素時,.children 屬性會給你一個包含這些子元素的列表。

這不是一個普通的列表,而是一個 HTMLCollection,這意味著它是即時更新的——如果你向這個元素添加或移除子元素,這個列表會自動更新。

補充一:HTMLCollection 是什麼

HTMLCollection 是一個類陣列物件,但它不是一個真正的陣列。

你可以使用索引來訪問陣列中的元素,也可以使用 length 屬性來獲取陣列中元素的數量。

但要注意,它不支持陣列的方法,如 forEach 或 map,除非你先將它轉換成一個真正的陣列。

補充二:.children 與 .childNodes

.children 只包括元素節點,也就是那些實實在在的HTML標籤,比如<div>、<span>等等。

它不包括文本節點(就是直接放在元素內部的文字)或註釋節點(那些你在HTML中用 <!– –> 包起來的註釋)。

如果你想要獲取包括文本和註釋在內的所有類型的子節點,你應該使用 .childNodes屬性。

假想你的網頁是一本書,這本書裡有很多章節(元素節點),每個章節之間可能會有空白頁或註釋(文本節點和註釋節點)。

  • .children 就像是幫你找出這本書中所有的章節,但它會忽略掉所有空白頁和註釋,只給你章節本身。
  • .childNodes 則是給你這本書的完整內容列表,包括章節、空白頁和註釋,一點都不遺漏。

簡單來說,.children 只給你元素(章節),而 .childNodes 給你所有內容(包括章節、空白頁和註釋)。

限制

.children 非常有用,但它也有自己的限制。

它只能訪問第一層的子元素,如果你需要操作更深層次的子孫元素,就需要結合其他遍歷 DOM 的方法來實現。

這意味著,當你從一個父元素上使用 .children 屬性時,你將獲得一個包含所有直接子標籤(元素)的集合,但不會包含任何深層嵌套的子孫元素,也不會包含非元素類型的節點。

代碼範例

HTML 結構

<div id="parent">
    <div class="child-level-1">
        <div class="child-level-2">第二層子元素</div>
    </div>
    <!-- 註釋: 這是一個註釋節點,不會被 .children 屬性包括 -->
    <div class="child-level-1">
        <div class="child-level-2">另一個第二層子元素</div>
    </div>
</div>

JavaScript 代碼

var parentElement = document.getElementById("parent");
var children = parentElement.children;

console.log(children); 

若使用 console.log(children); 則會輸出類似以下內容:

HTMLCollection(2) [div.child-level-1, div.child-level-1]

當使用 .children 屬性時,它僅僅返回目標元素的一層直接子元素,而不會進一步返回更深層的子孫元素。

也就是說,對於有兩層或多層子元素的情況,.children 屬性只會涵蓋第一層的子元素,不包含任何更深層次的子孫元素。

這裡的 children 會是一個 HTMLCollection,包含了兩個 .child-level-1 的 <div> 元素。

即使這些 .child-level-1 的 <div> 元素內部還有 .child-level-2 的子元素,它們也不會被包含在從 parentElement 的 .children 屬性所返回的集合中。

如果你需要訪問更深層次的子孫元素,你需要對每一層的子元素分別使用 .children 屬性,或者使用其他方法,如 querySelector 或 querySelectorAll。

它們可以基於 CSS 選擇器直接選擇深層的元素。

結論

結論

經過本文的介紹,你現在應該對DOM中的兩個重要屬性——.parentNode和.children有了深入的理解。

使用.parentNode,我們可以向上導航,找到任何元素的直接父節點。

另一方面,.children讓我們能夠向下探索,獲取元素的所有直接子元素。

雖然這兩個屬性非常強大,但它們各自都有一些限制。.parentNode只能幫助我們訪問直接父節點,而.children 僅限於訪問第一層子元素。

因此,靈活運用它們,並結合其他 DOM 操作技巧,將使你在開發過程中更加游刃有餘。

Similar Posts