# Do You Know The Difference? (HTML Collection、NodeList) :::success :bookmark: 書籤 [TOC] ::: ## HTMLCollection & NodeList 當我們使用DOM提供的方法來獲取節點時,會根據語法的使用返回不同型態的資料。 直接來看範例 ***index.html*** ```htmlembedded= <div class="boxParent"> <p>Hello World</p> <div class="box"> <p>123</p> <span>456</span> 789 </div> </div> ``` ***app.js*** ```javascript= const box = document.querySelector(".box"); console.log(box.parentElement) // output: div.boxParent console.log(box.parentNode) // output: div.boxParent ``` 使用parentElement和parentNode返回的資料型態都是一樣的 那如果是用children和childNodes呢? ***app.js*** ```javascript= const box = document.querySelector(".box"); console.log(box.children); /* * output : * 0 : p * 1 : span * length : 2 * [[Prototype]] : HTMLCollection * */ console.log(box.childNodes); /* * output : * 0 : text * 1 : p * 2 : text * 3 : span * 4 : text * length : 5 * [[Prototype]] : NodeList * */ ``` 可以發現返回的分別是HTMLCollection 和 NodeList 型態,而這兩個有什麼差別呢? 我們可以展開Prototype看裡面提供的methods  這邊可以注意到,我們常用的陣列方法並沒有出現在裡面,像是map、filter等, 但NodeList有提供forEach方法而HTMLCollection則是沒有。 而要怎麼讓這些型態擁有map和filter方法呢? 很簡單,直接看以下程式碼: ***app.js*** ```javascript= const box = document.querySelector(".box"); console.log(Array.from(box.parentElement) // 直接轉成陣列 console.log(Array.from(box.parentNode)) // 直接轉成陣列 ``` 使用 **Array.from()** 後,可以看到Prototype如下:   ## getElementByClassName ? 現在我們使用DOM方法時,比較少用到getElement的方法,因為有querySelector和querySelectorAll可以使用,但有沒有好奇過getElement的方法和querySelector差在哪? getElement系列,只要是能夠返回多個元素(節點)的都會是HTMLCollection型態,這與NodeList差在哪裡? 直接來看以下程式碼: 我們把index.html改成以下 ***index.html*** ```htmlembedded= <div class="boxParent"> <div class="box"></div> <div class="box"></div> <div class="box"></div> </div> ``` ***app.js*** ```javascript= const boxes = document.getElementsByClassName("box"); console.log(boxes); /** * output : * 0 : div.box * 1 : div.box * 2 : div.box * length : 3 * [[Prototype]] : HTMLCollection * / ``` 可以看到返回的是HTMLCollection型態,還沒結束~ 我們接著看! ***app.js*** ```javascript= const boxes = document.getElementsByClassName("box"); console.log(boxes); const boxParent = document.querySelector(".boxParent"); const box = document.createElement("div"); box.classList.add("box"); boxParent.appendChild(box); console.log(boxes); ``` 以上的程式碼,輸出的結果會是....  可以看到HTMLCollection有 **即時更新(Live Updates)** 的特性。 現在換成我們常用的querySelectorAll! ***app.js*** ```javascript= const boxes = document.querySelectorAll(".box"); console.log(boxes); const boxParent = document.querySelector(".boxParent"); const box = document.createElement("div"); box.classList.add("box"); boxParent.appendChild(box); console.log(boxes); ``` 結果如下:  可以看到NodeList沒有 **即時更新(Live Updates)** 的特性。 ## 延伸 在我們使用childNodes的時候,有沒有發現底下的元素(節點)只有兩個,但返回的資料長度是五個!  這是因為文字也被當作是節點,所以我們程式碼裡面的文字789也算是一個。 但這樣加起來也才三個,那剩下的兩個是哪來的? 答案是換行! 我們實際展開來看就知道了~  \n 就是換行的意思,所以如果要只抓元素(節點)來使用的話,建議使用children然後用Array.from()轉型態就好了。 
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up