在學習操作DOM的過程中,常常搞不清楚什麼方法可以用在node還是element上,要使用textContent還是innerText?最後就會反正都試試看看是哪個中的心態,這樣真的很母湯啊。
來好好研究一下他們的不同之處!
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)
我們都知道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]
nodes
,有文字節點、元素節點...等等,除了 node.childNodes
其他返回的nodeList
都不是動態的。element
,而且都是動態的。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