昨天上班有閒就把手邊專案視覺的 jQuery 用 VanillaJS 重寫了一遍,藉此入門並理解 jQuery 的程式碼做了哪些事情,其中在使用 innerText
這個 API 時被 eslint-plugin-unicorn
警告了應使用 textContent
優先於 innerText
,於是就花了點時間瞭解這兩個 API 的細部差異。
innerText
和 textContent
通常都被使用於「取得元素內的文字」時。假設我有一段 html
:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>repl.it</title>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<h1>Hello world</h1>
<script src="script.js"></script>
</body>
</html>
假如我要取得 h1
元素中的文字時:
const h1 = document.querySelector('h1')
console.log(h1.innerText)
console.log(h1.textContent)
打開終端機,兩邊印出的結果都是:
在一個簡單範例中會出現相同的結果,在不同情況時就會有很大的差異。
回傳的值
節錄 MDN 對於兩個 API 的描述:
Node.innerText 是一個代表節點及其後代之「已渲染」(rendered)文字內容的屬性。
Node.textContent 屬性表示了節點或其後代的文字內容。
已渲染指的是什麼?簡單地說,innerText
回傳「實際所見的內容」,我們針對 h1
加入一點點的 CSS:
h1 {
text-transform: uppercase;
}
在網頁中我們會看到被 CSS 改為大寫的 HELLO WORLD,接著到終端機:
從這邊就能很清楚地了解,innerText
取得的是被 CSS 調整過樣式後渲染的文字;textContent
則是實際取得節點中的文字內容。
再看一個例子,拿掉 CSS,這次我們在 h1
中加入一個 span
元素,並將其設定為 display:none
:
<h1>Hello world<span style="display:none;">!!!</span></h1>
終端機:
由於 span
在畫面上並不會出現,innerText
自然不會取到它的值。另外,當我們使用到例如換行的 br
元素時:
<h1>Hello world, <br/>I love Kanao</h1>
innerText
回傳的會是換行的結果;textContent
則會忽略掉它。
其他區別
如果有去看 MDN 對於兩者介紹頁面的話,會發現 innerText
被歸類在 HTMLElement
、textContent
則被歸類在 Node
。
innerText
因為最早是由 IE 自己提出的規範,這個 API 可能會碰到跨瀏覽器的問題(如 Firefox),不過現在不會有這樣的問題了。
此外則是效能問題,由於 innerText
需要經由 layout 確定使用者所見,效能會較 textContent
差,不過這要在資料非常龐大的時候才能看出毫秒的區別。
對於 innerText
和 textContent
的筆記就到這邊,如果想要深入理解,我底下會貼參考過的資料,如果內文有任何錯誤也煩請不吝指出,謝謝大家。
References: