innerText/textContent

 這是JavaScript DOM 操作中的一個重要觀念。

結論先行:絕大多數情況下,你應該優先使用 textContent

innerTexttextContent 都可以用來變更 div 的文字,但在很多情況下,它們的行為有著關鍵的區別。


快速比較表

特性textContentinnerText
性能快得多較慢
CSS 感知 (忽略 CSS) (會考慮 CSS 樣式)
內容取得所有節點的文字內容,包含 <script><style>只取得人類可見的文字內容
空白與換行回傳原始的空白和換行符號模仿瀏覽器渲染,會壓縮空白並轉換換行
推薦度高度推薦 (首選)僅在特定情況下使用

詳細解釋與範例

讓我們用一個 HTML 結構來看看它們在「讀取」時的區別,這能幫助你理解為什麼在「寫入」時 textContent 是更好的選擇。

HTML 範例:

<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

留言

這個網誌中的熱門文章

Offscreen Canvas

外部網頁新增 Google 日曆行程(URL模板)

計算 Canvas 文字最大字體