JavaScript >> Javascript 文檔 >  >> Tags >> DOM

如何遍歷 DOM

本文最初是為 DigitalOcean 編寫的 .

簡介

本系列的上一篇教程,如何訪問 DOM 中的元素,介紹瞭如何使用 document 的內置方法 對象通過 ID、類、標籤名稱和查詢選擇器訪問 HTML 元素。我們知道 DOM 被構造為具有 document 的節點樹 根節點和每個其他節點(包括元素、註釋和文本節點)作為各種分支。

通常,您會希望在不事先指定每個元素的情況下在 DOM 中移動。學習如何在 DOM 樹上上下導航以及從一個分支移動到另一個分支對於理解如何使用 JavaScript 和 HTML 至關重要。

在本教程中,我們將介紹如何使用父、子和兄弟屬性遍歷 DOM(也稱為遍歷或導航 DOM)。

設置

首先,我們將創建一個名為 nodes.html 的新文件 由以下代碼組成。

<!DOCTYPE html>
<html>
  <head>
    <title>Learning About Nodes</title>

    <style>
      * {
        border: 2px solid #dedede;
        padding: 15px;
        margin: 15px;
      }
      html {
        margin: 0;
        padding: 0;
      }
      body {
        max-width: 600px;
        font-family: sans-serif;
        color: #333;
      }
    </style>
  </head>

  <body>
    <h1>Shark World</h1>
    <p>
      The world's leading source on <strong>shark</strong> related information.
    </p>
    <h2>Types of Sharks</h2>
    <ul>
      <li>Hammerhead</li>
      <li>Tiger</li>
      <li>Great White</li>
    </ul>
  </body>

  <script>
    const h1 = document.getElementsByTagName('h1')[0]
    const p = document.getElementsByTagName('p')[0]
    const ul = document.getElementsByTagName('ul')[0]
  </script>
</html>

當我們在網絡瀏覽器中加載文件時,我們會看到如下圖所示的渲染。

在這個示例網站中,我們有一個包含一些元素的 HTML 文檔。 style 中添加了一些基本的 CSS 標籤使每個元素明顯可見,並且在 script 中創建了一些變量 為了便於訪問一些元素。由於每個 h1 只有一個 , p , 和 ul ,我們可以訪問每個 getElementsByTagName 上的第一個索引 屬性。

根節點

document object 是 DOM 中每個節點的根。這個對像其實是window的一個屬性 object,它是代表瀏覽器中選項卡的全局頂級對象。 window 對象可以訪問工具欄、窗口的高度和寬度、提示和警報等信息。 document 由內部 window 內部的內容組成 .

下面是一個由每個文檔將包含的根元素組成的圖表。即使一個空白的 HTML 文件被加載到瀏覽器中,這三個節點也會被添加並解析到 DOM 中。

屬性 節點 節點類型
document #document DOCUMENT_NODE
document.documentElement html ELEMENT_NODE
document.head head ELEMENT_NODE
document.body body ELEMENT_NODE

html , head , 和 body 元素是如此常見,它們在 document 上有自己的屬性 .

打開控制台 在 DevTools 中並通過提交它們並查看輸出來測試這四個屬性中的每一個。你也可以測試h1 , p , 和 ul 由於我們在 script 中添加的變量,這將返回元素 標記。

父節點

DOM 中的節點稱為父節點、子節點和兄弟節點,具體取決於它們與其他節點的關係。 父母 任何節點的節點是比它高一級的節點,或者更接近 document 在 DOM 層次結構中。有兩個屬性可以獲取父級——parentNodeparentElement .

屬性 得到
parentNode 父節點
parentElement 父元素節點

在我們的 nodes.html 例子:

  • htmlhead 的父級 , body , 和 script .
  • bodyh1 的父級 , h2 , pul ,但不是 li , 因為 libody 低兩層 .

我們可以測試我們的 p 的父級是什麼 元素與 parentNode 財產。這個p 變量來自我們自定義的 document.getElementsByTagName('p')[0] 聲明。

p.parentNode;
控制台
<body>
  ...
</body>

p 的父級 是 body ,但是我們怎麼才能得到上面兩層的祖父母呢?我們可以通過將屬性鏈接在一起來做到這一點。

p.parentNode.parentNode;
控制台
<html>
  ...
</html>

使用 parentNode 兩次,我們檢索了 p 的祖父母 .

有一些屬性可以檢索節點的父節點,但它們之間只有一個很小的區別,如下面的這段代碼所示。

// Assign html object to html variable
const html = document.documentElement;

console.log(html.parentNode); // > #document
console.log(html.parentElement); // > null

幾乎任何節點的父節點都是元素節點,因為文本和註釋不能是其他節點的父節點。但是,html 的父級 是一個文檔節點,所以 parentElement 返回 null .一般情況下,parentNode 在遍歷 DOM 時更常用。

子節點

孩子們 一個節點是比它低一級的節點。任何超過一層嵌套的節點通常稱為後代。

屬性 得到
childNodes 子節點
firstChild 第一個子節點
lastChild 最後一個子節點
children 元素子節點
firstElementChild 第一個子元素節點
lastElementChild 最後一個子元素節點

childNodes 屬性將返回節點的每個子節點的實時列表。您可能期望 ul 獲取三個 li 的元素 元素。讓我們測試它檢索到的內容。

ul.childNodes;
控制台
;(7)[(text, li, text, li, text, li, text)]

除了三個li 元素,它還獲得四個文本節點。這是因為我們編寫了自己的 HTML(它不是由 JavaScript 生成的)並且元素之間的縮進在 DOM 中被計為文本節點。這並不直觀,因為 Elements DevTools 的 tab 去掉空白節點。

如果我們嘗試使用 firstChild 更改第一個子節點的背景顏色 屬性,它會失敗,因為第一個節點是文本。

ul.firstChild.style.background = 'yellow';
控制台
Uncaught TypeError: Cannot set property 'background' of undefined

children , firstElementChildlastElementChild 在這些類型的情況下存在屬性以僅檢索元素節點。 ul.children 只會返回三個 li 元素。

使用 firstElementChild ,我們可以改變第一個li的背景顏色 在 ul .

ul.firstElementChild.style.background = 'yellow';

當您運行上述代碼時,您的網頁將更新以修改背景顏色。

在進行本例中的基本 DOM 操作時,特定於元素的屬性非常有用。在 JavaScript 生成的 Web 應用程序中,選擇所有節點的屬性更有可能被使用,因為在這種情況下將不存在空白換行符和縮進。

一個for...of 循環可用於遍歷所有 children 元素。

for (let element of ul.children) {
  element.style.background = 'yellow';
}

現在,每個子元素都有一個黃色背景。

由於我們的 p 元素內部同時包含文本和元素,childNodes 屬性有助於訪問該信息。

for (let element of p.childNodes) {
  console.log(element);
}
控制台
"The world's leading source on "
<strong>​shark​</strong>​
" related information."

childNodeschildren 不返回具有所有 Array 屬性和方法的數組,但它們的外觀和行為類似於 JavaScript 數組。您可以通過索引號訪問節點,或者找到它們的 length 屬性。

document.body.children[3].lastElementChild.style.background = 'fuchsia';

上面的代碼會找到最後一個子元素(li ) 的第四個子元素 (ul ) 的 body 並應用樣式。

使用 parent 和 child 屬性,您可以檢索 DOM 中的任何節點。

兄弟節點

兄弟姐妹 一個節點是 DOM 中同一樹級別上的任何節點。兄弟節點不必是同一類型的節點 - 文本、元素和註釋節點都可以是兄弟節點。

屬性 得到
previousSibling 上一個兄弟節點
nextSibling 下一個兄弟節點
previousElementSibling 上一個兄弟元素節點
nextElementSibling 下一個兄弟元素節點

同級屬性的工作方式與子節點相同,因為有一組屬性可以遍歷所有節點,而一組屬性僅適用於元素節點。 previousSiblingnextSibling 將獲取緊接在指定節點之前或之後的下一個節點,並且 previousElementSiblingnextElementSibling 只會獲取元素節點。

在我們的 nodes.html 例如,我們選擇 ul 的中間元素 .

const tiger = ul.children[1];

由於我們是從頭開始創建 DOM 而不是作為 JavaScript Web 應用程序創建的,因此我們需要使用元素兄弟屬性來訪問前一個和下一個元素節點,因為 DOM 中存在空白。

tiger.nextElementSibling.style.background = 'coral';
tiger.previousElementSibling.style.background = 'aquamarine';

運行此代碼應該已應用 coralHammerhead的背景 和 aquamarineGreat White的背景 .

兄弟屬性可以鏈接在一起,就像父屬性和節點屬性一樣。

結論

在本教程中,我們介紹瞭如何訪問每個 HTML 文檔的根節點以及如何通過父、子和兄弟屬性遍歷 DOM 樹。

借助您在如何訪問 DOM 中的元素和本教程中學到的知識,您應該能夠自信地訪問任何網站的 DOM 中的任何節點。


Tutorial JavaScript 教程
  1. 可維護的 JavaScript — 數字和 Null

  2. Kubernetes 和 OpenShift:2021 年最好的

  3. Express GET 請求未重新加載頁面

  4. 生成式 SVG 入門工具包

  5. JavaScript 中 2 個有用的輪詢函數

  6. 如何返回計數結果而不是閉包函數?

  7. 如何編寫和發布你的第一個 NPM 包

  1. 更改遊戲而不更改之前添加的遊戲

  2. 檢測輸入框中的粘貼

  3. 帶有列表項菜單的代碼 javascript 有什麼問題?

  4. 領帶仍在運行中獎消息?

  5. JavaScript 和 jQuery PDF 查看器插件

  6. Rust for Web:使用 Rust 為 NodeJS 開發人員介紹 Web 開發

  7. 如何檢測文本框的內容已更改

  1. 子數組和等於 K,應用數學。

  2. Nuxt 3 的新功能

  3. 我需要知道我應該採取什麼路徑來創建一個應用程序,該應用程序在從列表中選擇歌曲時顯示歌曲的音符。

  4. 高級 TypeScript:重塑 lodash.get