innerText/textContent
這是JavaScript DOM 操作中的一個重要觀念。
快速比較表
詳細解釋與範例
<div id="myDiv">
Hello <span>World!</span>
<style>div { color: red; }</style>
<b style="display: none;">這段文字是隱藏的。</b>
</div>
const myDiv = document.getElementById('myDiv');
// 使用 textContent
console.log(myDiv.textContent);
// 輸出:
// "
// Hello World!
// div { color: red; }
// 這段文字是隱藏的。
// "
// 使用 innerText
console.log(myDiv.innerText);
// 輸出:
// "Hello World!"
**從讀取範例中可以看出關鍵差異:**
1. **`textContent`**:
* **性能快**:它只是簡單地遍歷所有 DOM 節點,將它們的文字內容串接起來。它完全不關心頁面是如何渲染的。
* **內容完整**:它會返回所有子節點的文字,**包括 `<style>`、`<script>` 標籤的內容,以及被 CSS 隱藏的元素 (`display: none`)**。
* **格式保留**:它會保留 HTML 原始碼中的空白和換行。
2. **`innerText`**:
* **性能慢**:為了計算出哪些文字是「可見」的,它需要觸發瀏覽器的 **reflow (重排)**。瀏覽器需要計算 CSS 樣式,確定元素的佈局和可見性。這是一個非常耗費資源的操作。
* **感知 CSS**:它只會返回用戶在瀏覽器畫面上實際能看到的文字。它會忽略被 `display: none` 或 `visibility: hidden` 隱藏的內容,也不會包含 `<script>` 或 `<style>` 標籤的內容。
* **格式化**:它會模仿瀏覽器顯示文字的方式,例如將多個空白壓縮成一個,並處理換行符 (`<br>` 會變成 `\n`)。
### 為什麼「變更文字」時推薦用 `textContent`?
當你**設定 (寫入)** 文字時,雖然 `myDiv.textContent = '新文字'` 和 `myDiv.innerText = '新文字'` 在簡單情況下看起來效果一樣,但選擇 `textContent` 仍然是最佳實踐:
1. **性能 (Performance)**:因為 `innerText` 需要感知 CSS,即使在設定值時,它也可能觸發不必要的性能開銷。而 `textContent` 只是簡單地替換掉節點下的所有內容為一個新的文字節點,過程非常直接且高效。
2. **可預測性 (Predictability)**:`textContent` 的行為非常單純:移除所有子節點,插入一個包含你指定文字的文字節點。它的行為不會因為元素的 CSS 樣式而改變,程式碼更穩健。
3. **安全性 (Security)**:`textContent` 會將你賦予的所有內容都視為純文字。這意味著如果你的文字中包含 HTML 標籤(例如 `<script>alert('XSS')</script>`),它會被當作普通文字顯示在頁面上,而不會被執行。這可以有效防止 XSS (跨站腳本攻擊)。
```javascript
const myDiv = document.getElementById('myDiv');
// 這將會在頁面上顯示文字 "<b>Hello</b>",而不是一個加粗的 "Hello"
myDiv.textContent = '<b>Hello</b>';
```
### 什麼時候才應該使用 `innerText`?
只有在你需要**獲取或複製一個元素在頁面上被渲染出來的、用戶可見的文字**時,才應該使用 `innerText`。例如,你想要實作一個「複製文章內容」的功能,並且不希望複製到文章中被 CSS 隱藏的註解或元數據。
### 重要的提醒:關於 `innerHTML`
你可能還會看到 `innerHTML`。它與前兩者完全不同:
* **`innerHTML`**:會解析你賦予的字串並將其轉換為 HTML 元素。
**絕對不要用 `innerHTML` 來設定純文字**,尤其是當文字來自用戶輸入時,因為這會造成嚴重的 XSS 安全漏洞。
```javascript
// 危險!如果 evilString 是 "<img src=x onerror=alert('hacked')>",這段程式碼就會被執行!
const evilString = getUserInput();
myDiv.innerHTML = evilString;
要變更 div 的文字,請使用 textContent。 它更快、更可預測、更安全。只有在你需要 讀取 元素可見 的文字時,才考慮使用 innerText。除非你明確知道你需要插入 HTML 元素,否則 避免使用 innerHTML 。
留言
張貼留言