天天看點

你可能沒有聽說過 js中的 DOM操作還有這個: HTMLCollection 和 NodeList⛱️序言🎈一、基礎知識🪁二、異同點📞三、結束語🐣彩蛋 One More Thing

你可能沒有聽說過 js中的 DOM操作還有這個: HTMLCollection 和 NodeList⛱️序言🎈一、基礎知識🪁二、異同點📞三、結束語🐣彩蛋 One More Thing

一文了解DOM操作中的HTMLCollection和NodeList

  • ⛱️序言
  • 🎈一、基礎知識
    • 1. 定義
      • (1)HTMLCollection
      • (2)NodeList
    • 2. 屬性和方法
      • (1)HTMLCollection
      • (2)NodeList
  • 🪁二、異同點
    • 1. HTMLCollection 與 NodeList 的差別
    • 2. querySelectorAll 和 getElementsByTagName 的差別
      • (1)querySelectorAll
      • (2)getElementsByTagName
  • 📞三、結束語
  • 🐣彩蛋 One More Thing
    • (:參考資料
    • (:番外篇

⛱️序言

猶記得上回有一次面試的時候被問到

htmlCollection

和數組的關系。當時的我心裡想的是,

html

中的集合和數組的關系,那解題就是說

set

和數組的關系?

于是……面試官當下立即糾正我,

htmlCollection

是單詞連在一起的,是

js

的一個内容。當時我可能是想……找個地洞鑽……

你可能沒有聽說過 js中的 DOM操作還有這個: HTMLCollection 和 NodeList⛱️序言🎈一、基礎知識🪁二、異同點📞三、結束語🐣彩蛋 One More Thing

不會的咋還是得虛心接收,查漏補缺還是比較合理。經過一系列的資料查詢和總結之後,得出以下總結。

下面開始進入本文的講解~🙋

🎈一、基礎知識

1. 定義

(1)HTMLCollection

  • HTMLCollection

    表示一個包含了元素(元素順序為文檔流中的接口)的集合(通用集合),還提供了從該集合中選擇元素的屬性和方法。
  • 例如使用

    getElementsByTagName()

    方法傳回的就是一個

    HTMLCollection

    對象。

(2)NodeList

  • NodeList

    對象是節點的集合。
  • 通過以下方法,可以擷取到

    NodeList

    對象。主要有:①在一些舊版本浏覽器中的方法,比如

    getElementsClassName()

    方法,傳回的是

    NodeList

    對象,而不是

    HTMLCollection

    對象。②所有浏覽器的

    Node.childNodes

    屬性傳回的都是

    NodeList

    對象。③大部分浏覽器的

    document.querySelectorAll()

    傳回的是

    NodeList

    對象。
  • 我們可以通過以下代碼進行驗證:
    document.body.childNodes instanceof NodeList // true
    document.querySelector('body') instanceof NodeList // true or false
    document.getElementByClassName('body') instanceof NodeList // true or false
               

2. 屬性和方法

(1)HTMLCollection

HTMLCollection

對象中的屬性和方法,舉例兩個:

  • item(index)

    —— 傳回

    HTMLCollection

    中指定索引的元素,如果不存在則傳回

    null

  • length

    (隻讀) —— 傳回

    HTMLCollection

    中元素的數量。

接下來用一個例子來進行闡述驗證。具體代碼如下:

document.getElementsByTagName('body') instanceof HTMLCollection // true

const htmlCollection = document.getElementsByTagName('body')
console.log(htmlCollection.item(0)) // <body>...</body>
console.log(htmlCollection.length()) // 1
           

(2)NodeList

NodeList

對象中的屬性和方法主要有以下幾種。包括:

  • item()

    —— 傳回某個元素基于文檔數的索引;
  • length()

    —— 傳回

    NodeList

    中的節點數量;
  • NodeList.forEach()

    —— 該方法用于周遊

    NodeList

    中的所有成員。它接收一個回調函數作為參數,每周遊一回就要執行這個回調函數一次,用法與數組執行個體的

    forEach

    方法是完全一緻的;
  • NodeList.keys()/values()/entries()

    —— 對于這三個方法來說,它們都會傳回一個

    ES6

    的周遊器對象,可以通過

    for…of…

    來進行循環周遊,以便于擷取每一個成員的資訊。

同時,需要注意以上三者的差別,分别如下:

  • keys() —— 指的是傳回鍵名的周遊器;
  • values() —— 指的是傳回鍵值的周遊器;
  • entries() —— 指的是傳回的周遊器要同時包含鍵名和鍵值的資訊。

我們寫點代碼來論證以上内容。具體代碼如下:

const nodelist = document.querySelectorAll('body')

console.log(nodelist.item(0)) // <body>...</body>
console.log(nodelist.length) // 1
console.log(nodelist.forEach(item => console.log(item))) // <body>...</body>

for(var key of nodelist.keys()) {
  console.log(nodelist[key]) // <body>...</body>
}

for(var value of nodelist.values()) {
  console.log(value) // <body>...</body>
}

for(var entry of nodelist.entries()) {
  console.log(entry) // [0, body]
}
           

🪁二、異同點

1. HTMLCollection 與 NodeList 的差別

HTMLCollection NodeList
集合 元素的集合 節點的集合
靜态和動态 HTMLCollection 是動态綁定的,是一個動态集合。DOM 樹發生變化,HTMLCollection 也會随之變化,說明其節點的增删是敏感的 NodeList 是一個靜态集合,其不受 DOM 樹元素變化的影響;相當于是 DOM 樹、節點數量和類型的快照,也就是說對節點進行增删操作時,NodeList 是感覺不到的。但是對節點内部内容修改,是可以感覺得到的,比如修改 innerHTML
節點 不包含屬性節點和文本節點 隻有 NodeList 對象有包含屬性節點和文本節點
元素擷取方式 HTMLCollection 元素可以通過 name,id 或 index 索引來擷取 NodeList 隻能通過 index 索引來擷取
僞數組 HTMLCollection 和 NodeList 都是類數組,不是數組,隻是長得像數組而已。是以無法使用數組的方法,比如: pop(),push(),或 join() 等等 與 HTMLCollection 一樣

2. querySelectorAll 和 getElementsByTagName 的差別

在上述的表格中我們可以了解到,

HTMLCollection

是動态集合,當

DOM

樹發生變化時,

HTMLCollection

也會随之改變。而

NodeList

是靜态集合,當

DOM

樹發生變化時,

NodeList

不會受到

DOM

樹變化的影響。我們來舉兩個例子進行闡述說明。

(1)querySelectorAll

先附上代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>htmlCollection和NodeList</title>
</head>
<body>
    <ul>
        <li></li>
        <li></li>
        <li>MondayLab</li>
        <li></li>
        <li></li>
    </ul>
    <script>
        var oldUl = document.querySelectorAll('ul')[0];
        var oldLi = document.querySelectorAll('li');

        console.log(oldUl); // NodeList[body]
        console.log(oldLi.length); // 5

        var newLi = document.createElement('li');
        oldUl.appendChild(newLi);

        console.log(oldLi.length); // 5
        var length = oldLi.length - 1;
        oldLi[length].innerHTML = 'monday';
        console.log(oldLi[length].innerHTML); // monday 
        console.log(oldLi.length); // 5 → 雖然通過innerHTML可以讀到文本節點的内容,但是長度依舊不變,還是5
    </script>
</body>
</html>
           

大家可以看到,使用

querySelectorAll

來擷取

<li>

,傳回的是一個

NodeList

的集合。且當頁面

DOM

結構發生改變時,其長度不會發生任何的改變。但是當改變

innerHTML

時,則文本節點的内容會發生改變。值得注意的是,即使

innerHTML

改變

DOM

的結構,但長度依舊是不變的,還是

5

(2)getElementsByTagName

先附上代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>HTMLCollection</title>
</head>
<body>
    <ul>
        <li></li>
        <li></li>
        <li>MondayLab</li>
        <li></li>
        <li></li>
    </ul>
    <script>
        var oldUl = document.getElementsByTagName('ul')[0];
        var oldLi = document.getElementsByTagName('li');

        console.log(oldUl); // HTMLCollection[body]
        console.log(oldLi.length); // 5

        var newLi = document.createElement('li');
        oldUl.appendChild(newLi);

        console.log(oldLi.length); // 6 → 順利改變 DOM 的結構
    </script>
</body>
</html>
           

大家可以看到,使用

getElementByTagName

時,擷取的是一個

HTMLCollection

集合,這個時候說明對節點進行增删操作時,頁面的

DOM

結構會發生改變,且

HTMLCollection

将實時地擷取到集合的長度。

📞三、結束語

寫到這裡的時候,不得不感概

js

DOM

操作是如此的強大,也突然就明白了自己之前寫代碼的時候為啥會遇到那麼多坑。如果在學習之初就追溯于原理,可能跳的坑應該就能少很多了。

講到這裡,關于

HTMLCollection

NodeList

的内容就結束啦!希望對大家有幫助~

彩蛋有幾篇我看過還比較好了解的文章,有需要可以當擴充知識進行擴充哦~

🐣彩蛋 One More Thing

(:參考資料

lio_zero👉HTMLCollection和NodeList的差別

Snandy👉将HTMLCollection/NodeList/僞數組轉換成數組

binyellow👉DOM操作,HTMLCollection、NodeList

愛民👉NodeList 和 HTMLCollection

(:番外篇

  • 關注公衆号星期一研究室,第一時間關注優質文章,更多精選專欄待你解鎖~
  • 如果這篇文章對你有用,記得留個腳印jio再走哦~
  • 以上就是本文的全部内容!我們下期見!👋👋👋

繼續閱讀