今天看Node对象时瞥了一眼textContent,没想到有很多需要注意的地方,并且有不少可替代innerText和innerHTML的情境。
<div id="text">
<span>You</span>
<span>are</span>
<span>being</span>
<span>watched</span>
</div>
<script>
let text = document.getElementById('text')
console.log('innerText', text.innerText)
console.log('innerHTML', text.innerHTML)
console.log('textContent', text.textContent)
</script>
以上一段代码块,在工作台会分别打印出怎样的结果?先自己想想哦。
innerText You are being watched
innerHTML
<span>You</span>
<span>are</span>
<span>being</span>
<span>watched</span>
textContent
You
are
being
watched
能看出除了innerHTML打印出了 .text 的html之外,innerText 和 textContent 均打印出了其包含的文字。区别在于 innerText 打印的是一行,正如此元素在页面展示的一样,而 textContent 分行打印。这就与我们要说的二者差别有关了。
首先我们要了解,textContent 的值依据节点的不同而不同,例如文本节点与元素节点的表现。文本节点的 textContent 会返回这个元素包含的text文本,而元素节点返回的是此节点所有子节点的 textContent 的连接(concatenation)。
在这个例子里,div.text 这个节点的子节点除了我们一般认为的 span 之外,还有换行的 text 节点。没错,即使是 html 文档中的换行,在DOM中都会把它看做一个 text 节点。而 textContent 既然要打印所有子节点,自然会打印出 ‘换行’节点了。
我们把 html 文档中的换行去掉再打印一下:
<div id="text">
<span>You</span><span>are</span><span>being</span><span>watched</span>
</div>
innerText Youarebeingwatched
innerHTML
<span>You</span><span>are</span><span>being</span><span>watched</span>
textContent
Youarebeingwatched
innerText 与 textContent 还有一处在性能上的差异。innerText 并不像 textContent 返回所有节点内容,而是会考虑 style 的影响,它不会返回 hidden 掉的元素。而这重考虑,又会导致页面的回流,回流很吃内存,一般来说应尽量避免回流。
在MDN里提到的 innerHTML 和 textContent 的区别之一也是性能上的,innerHTML 有一步将内容解析为 html,而textContent 不需要这步,所以某种情境下,textContent 也比 innerHTML 在性能表现上更优越。
综上,以后遇到 innerHTML 或者 innerText 的使用场景,可以多考虑一下角落里的 textContent。PS: 此属性的兼容性也很漂亮。