iT邦幫忙

2022 iThome 鐵人賽

DAY 19
1
Modern Web

前端蛇行撞牆記系列 第 19

Day19 前端蛇行撞牆記 - node v.s element

  • 分享至 

  • xImage
  •  

前言

在學習操作DOM的過程中,常常搞不清楚什麼方法可以用在node還是element上,要使用textContent還是innerText?最後就會反正都試試看看是哪個中的心態,這樣真的很母湯啊。

來好好研究一下他們的不同之處!

Node, Element

Node是所有在DOM下的node Object,而element只是node的其中一種類型


出自:What is the difference between node and element?

看上面那張圖可以知道其實所有在document底下的都是Node,奇怪怎麼都沒有element?

我們可以透過.nodetype來得知我們所認為的element是屬於哪種node
先做個簡單的範例:

<body>
    <h1>My Page</h1>
    <div class="text">
      <p>Thank you for visiting my web page!</p>
      <p>hope you will like it!</p>
    </div>
</body>
<script>
    const body = document.querySelector("body");
    const p = document.querySelector("p");
    const h1 = document.querySelector("h1");

    console.log(body.nodeType); //1
    console.log(p.nodeType); //1
    console.log(h1.nodeType); //1
</script>

結果全部都會印出1,再對照nodetype表,<h1><p><body> 是屬於 Node.ELEMENT_NODE value:1,所以說他們屬於node的element。

所有node的類型:
Node.ELEMENT_NODE (1)
Node.ATTRIBUTE_NODE (2)
Node.TEXT_NODE (3)
Node.CDATA_SECTION_NODE(4)
Node.PROCESSING_INSTRUCTION_NODE (7)
Node.COMMENT_NODE (8)
Node.DOCUMENT_NODE (9)
Node.DOCUMENT_TYPE_NODE (10)
Node.DOCUMENT_FRAGMENT_NODE (11)

Nodelist, HTMLCollection

我們都知道document.querySelectorAll()返回的會是一個Nodelist,然而除了這個以外,我最常使用的就是node.childNodes,這個功能是會找到要找到node下面的所有節點,但每次都很麻煩,因為他不會只返回element,我必須要先看有什麼,然後再慢慢選要選到哪個index

這樣講也是霧煞煞,先來看範例:

<body>
    <h1>My Page</h1>
    <div class="text">
      <p>Thank you for visiting my web page!</p>
      <p>hope you will like it!</p>
    </div>
</body>

現在真的很想要選到<div>裡面的第二個<P>,想要動態轉換文字,但因為我不想特別給他套上class名稱,因為<div>有class所以我想從他開始選:

const div = document.querySelector(".text");

console.log(div.childNodes);
// NodeList(5)[text, p, text, p, text]

會返回一個nodelist,可是裡面明明有只有兩個<p>,為什麼會有5個nodes?那是因為node也會包含空格,所以那個text就是每個element之間的空格。

每一次都需要先看好裡面有什麼,再用對照的index選到要選到的node

console.log(div.childNodes[3])
// <p>hope you will like it!</p>

選到了!但每次都要這樣兩步驟太麻煩了。

如果今天使用的是element.children就只會返回HTMLCollection,而裡面就只有<p>的element在裡面,這樣就比較好選到要第幾個index了。

const div = document.querySelector(".text");

console.log(div.children);
// HTMLCollection(2)[p, p]

總結一下兩者的差異:

  • nodeList 包含所有nodes,有文字節點、元素節點...等等,除了 node.childNodes 其他返回的nodeList都不是動態的。
  • HTMLCollection 只會包含element,而且都是動態的。

innerText, textContent

  • node.textContent 單純讀取文本,看不到CSS,隱藏的部分也沒有用
  • element.innerText 會連同CSS的部分也讀取到,所以如果有隱藏的文字也會被隱藏。

範例:
(這個範例有點不同,我在<p>裡面又包了<span>,然後<span>又給他一個字型大寫的CSS)

<style>
    span {
      text-transform: capitalize;
    }
</style>
<body>
    <h2>My Page</h2>
    <p id="content">
      Thank you for visiting my web page!
      <span>hehe</span>
    </p>
</body>
<script>
    const p = document.querySelector("p");
    console.log(p.textContent);
    console.log(p.innerText);
</script>

結果:
上:node.textContent
下:element.innerText

可以看到p.innerText<span>的字型有被CSS影響變成大寫的「Hehe」了,
但比較奇妙是p.textContent看起來像是有呈現在code長起來的樣子,並不會在乎<span>是要並排的效果。

總結:

雖然其實都可以用,都找得到字,可是還是要清楚這兩者之間的差異,不然如果使用element.innerText結果出來的字都被CSS影響了,應該也是很傻眼。而且由於element.innerText會用CSS,效能可能沒有這麼好。
所以與其踩到坑,不如先了解一下!

但我應該以後都會用node.textContent了吧

就這樣了~以後操作DOM的時候應該會更有意識自己選到什麼了!

明天見囉!


參考資料:What's the Difference between DOM Node and Element?
小tips: JS DOM innerText和textContent的区别
Difference between Node object and Element object?
What is the difference between node and element?
HTMLCollection vs NodeList


上一篇
Day18 前端蛇行撞牆記 - volta刪除已下載node版本的方法
下一篇
Day20 前端蛇行撞牆記 - 製作簡易帳號密碼登入儲存/ localStroge
系列文
前端蛇行撞牆記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言