HTMLElement.innerText 和 Node.textContent傻傻分不清楚?
當我們想要訪問DOM中的文本內容時,肯定會第一時間想到HTMLElement.innerText?。事實上,JavaScript 提供了兩個可用于「訪問元素文本內容的」屬性:Node.textContent和HTMLElement.innerText。在大多數情況下,這兩者似乎可以互換。但我們在互換使用它們,往往會忽略兩者之間存在重要區別。
相似之處
我認為在深入研究差異之前確定這兩個屬性的相似之處很有幫助。這也將闡明它們在大多數情況下的使用方式。
假設有一個 HTML 元素,其中包含一些文本:
這兩個屬性都將返回元素的文本內容,包括任何子「元素」的文本內容。它們還將忽略元素內容中可能出現的「任何 HTML 標記。」而且,它們也可用于「設置元素的文本內容」。
差異
到目前為止,這兩個屬性似乎在做完全相同的事情。事實上,它們都提供了一些非常有用的便利功能。然而,當元素的內容稍微復雜一點時,它們開始表現出一些差異。
以下面的 HTML 元素為例:
讓我們看一下這兩個屬性各自的輸出,看看它們有何不同。
在這種情況下是完全不同的,對吧?HTMLElement.innerText應該大致「匹配用戶」在瀏覽器中看到的內容。另一種思考方式是它的輸出應該與用戶選擇元素的內容并將其復制到剪貼板時得到的結果非常相似。
根據這個定義,首先要注意的是「隱藏的元素被忽略了」。這適用于不呈現的元素,例如<style>和<script>?,也適用于使用 CSS 隱藏的元素。在此示例中,該<small>?元素是隱藏的,因此它不包含在 的輸出中HTMLElement.innerText。
其次, 的輸出HTMLElement.innerText?被「歸一化」。這意味著所有空格都折疊成一個空格,并且所有換行符都替換為單個換行符。如果存在,<br>標簽也會受到尊重,因此它們會被換行符替換。
我想說的最后一點是將「文本轉換」HTMLElement.innerText?應用于元素的內容。在本例中,元素被轉換為大寫,因此 的輸出反映了這一點。<strong>? HTMLElement.innerText
另一方面,Node.textContent?返回元素的「確切文本內容,包括任何空格和換行符。」然而,<br>?標簽在沒有任何替代品的情況下被剝離。它還包括任何隱藏元素的文本內容,例如<style>和<script>并且沒有應用任何文本轉換。
表現
可是等等!還有更多!雖然HTMLElement.innerText看起來是明智的選擇,但它帶有性能問題。為了弄清楚瀏覽器呈現的內容,必須考慮 CSS,觸發重排。這在計算上可能「很昂貴」,并且可能會造成無意的性能瓶頸。
在我看來,一個好的經驗法則是Node.textContent?盡可能使用純文本元素。對于更復雜的元素,請嘗試確定它們如何受布局和用戶交互的影響。例如,只呈現一次且永遠不會改變的復雜元素將是 的用例HTMLElement.innerText,但您可以將輸出存儲在變量中并重新使用它。
結論
HTMLElement.innerText并且Node.textContent是兩個非常相似的屬性,可用于訪問和操作元素的文本內容。但是,它們在一些重要方面有所不同,你應該了解這些差異以選擇最適合您需求的一種。始終檢查你的用例并考慮你的選擇對性能的影響。
- textContent會獲取所有元素的content,包括<script>和<style>元素或者可以說innerText的值依賴于瀏覽器的顯示,textContent依賴于代碼的顯示
- innerText返回值會被格式化,而textContent不會。textContent會把空標簽解析成換行(幾個空標簽就是幾行),innerText只會把block元素類型的空標簽解析換行,并且如果是多個的話仍看成是一個,而inline類型的原素則解析成空格
- innerText 會帶來性能影響(innerText會觸發reflow,而textContent不會)