今天看Node对象时瞥了一眼textContent,没想到有很多需要注意的地方,并且有不少可替代innerText和innerHTML的情境。

    1. <div id="text">
    2. <span>You</span>
    3. <span>are</span>
    4. <span>being</span>
    5. <span>watched</span>
    6. </div>
    7. <script>
    8. let text = document.getElementById('text')
    9. console.log('innerText', text.innerText)
    10. console.log('innerHTML', text.innerHTML)
    11. console.log('textContent', text.textContent)
    12. </script>

    以上一段代码块,在工作台会分别打印出怎样的结果?先自己想想哦。

    1. innerText You are being watched
    2. innerHTML
    3. <span>You</span>
    4. <span>are</span>
    5. <span>being</span>
    6. <span>watched</span>
    7. textContent
    8. You
    9. are
    10. being
    11. watched

    能看出除了innerHTML打印出了 .text 的html之外,innerText 和 textContent 均打印出了其包含的文字。区别在于 innerText 打印的是一行,正如此元素在页面展示的一样,而 textContent 分行打印。这就与我们要说的二者差别有关了。
    首先我们要了解,textContent 的值依据节点的不同而不同,例如文本节点与元素节点的表现。文本节点的 textContent 会返回这个元素包含的text文本,而元素节点返回的是此节点所有子节点的 textContent 的连接(concatenation)。
    在这个例子里,div.text 这个节点的子节点除了我们一般认为的 span 之外,还有换行的 text 节点。没错,即使是 html 文档中的换行,在DOM中都会把它看做一个 text 节点。而 textContent 既然要打印所有子节点,自然会打印出 ‘换行’节点了。
    我们把 html 文档中的换行去掉再打印一下:

    1. <div id="text">
    2. <span>You</span><span>are</span><span>being</span><span>watched</span>
    3. </div>
    4. innerText Youarebeingwatched
    5. innerHTML
    6. <span>You</span><span>are</span><span>being</span><span>watched</span>
    7. textContent
    8. Youarebeingwatched

    innerText 与 textContent 还有一处在性能上的差异。innerText 并不像 textContent 返回所有节点内容,而是会考虑 style 的影响,它不会返回 hidden 掉的元素。而这重考虑,又会导致页面的回流,回流很吃内存,一般来说应尽量避免回流。

    在MDN里提到的 innerHTML 和 textContent 的区别之一也是性能上的,innerHTML 有一步将内容解析为 html,而textContent 不需要这步,所以某种情境下,textContent 也比 innerHTML 在性能表现上更优越。

    综上,以后遇到 innerHTML 或者 innerText 的使用场景,可以多考虑一下角落里的 textContent。PS: 此属性的兼容性也很漂亮。