Node.textContent 属性表示一个节点及其后代的文本内容。
1. 语法
let text = element.textContent;
element.textContent = "some text";
2. 描述
- 如果 element 是 Document,DocumentType 或者 Notation 类型节点,则 textContent 返回 null。如果你要获取整个文档的文本以及CDATA数据,可以使用 document.documentElement.textContent。
- 如果节点是个CDATA片段,注释,ProcessingInstruction节点或一个文本节点,textContent 返回节点内部的文本内容(即 nodeValue)。
- 对于其他节点类型,textContent 将所有子节点的 textContent 合并后返回,除了注释、ProcessingInstruction节点。如果该节点没有子节点的话,返回一个空字符串。
- 在节点上设置 textContent 属性的话,会删除它的所有子节点,并替换为一个具有给定值的文本节点。
3. 与innerText的区别
Internet Explorer 引入了 node.innerText。innerText不是HTML的一个属性,而是浏览器自己实现的,所以不同的浏览器之间是有区别的,所以说如果想使用这个属性,最好先进行一下判断,
typeof textContent === 'string'
若结果等于string,则说明浏览器支持textContent;
若不等于string,说明浏览器不支持textContent,只需要使用innerText即可。
但就此引出一个问题,为何我们先判断textContent,而不是先按断innerText呢,也就是说,若浏览器同时支持textContent和innerText,我们会优先使用textContent。
为何要这样呢?
innerText与textContent意图类似,但有以下区别:
- textContent 会获取所有元素的内容,包括
<script>
和<style>
元素,然而 innerText 不会包含。 - innerText的返回值依赖于页面的显示(你在页面中看到的),而textContent依赖于代码的内容
比如有以下内容
<div>
outer
<span style="display: none"></span> // visibility: hidden
</div>
这个span标签不会在页面中显示,那么innerText不会返回隐藏元素(span)的文本,而textContent会。
此时就可以解释第一点的区别了, <script>
和 <style>
元素的内容再页面中是不会被显示的,所以用 innerText 获取不会返回,但是textContent会返回。
- 由于 innerText 受 CSS 样式的影响,依赖于页面的显示,它会触发回流(backflow),但textContent 可能不会触发回流。
回流:当render tree中的一部分或全部因为元素的规模尺寸、布局、隐藏等改变时,浏览器重新渲染部分DOM或全部DOM的过程。回流也被称为重排,其实从字面上来看,重排更容易让人形象易懂(即重新排版整个页面)。
重绘:当页面元素样式改变不影响元素在文档流中的位置时(如background-color,border-color,visibility),浏览器只会将新样式赋予元素并进行重新绘制操作。
什么时候会触发回流或重绘?
有大量的用户行为以及潜在的DHTML改变会触发回流。例如,改变浏览器窗口的大小,使用一些JavaScript方法,包括计算样式,对DOM进行元素的添加或删除,或是改变元素的class等。
添加或者删除可见的DOM元素;
元素位置改变;
元素尺寸改变——边距、填充、边框、宽度和高度;
内容变化,比如用户在input框中输入文字,文本或者图片大小改变而引起的计算值宽度和高度改变;
页面渲染初始化;
浏览器窗口尺寸改变,resize事件发生时;
计算offsetWidth和offsetHeight属性;
设置style属性的值;
回流必将引起重绘,而重绘不一定会引起回流。
浏览器认为你重新设置了innerText,会对你整个页面的渲染造成影响,所以这时候它会从当前的这个节点一直往回追溯,比如说从一个子节点找到它的父节点,从父节点再找到上一层父节点。一层一层往上找,一直找到根节点,执行这样一个逆向的,一步一步查找的这个过程,查找到了根节点,把整个树重新渲染一遍。这种情况称之为回流。
大家可以想象一下,浏览器执行这样操作的时候,对整个浏览器的性能影响是非常大的,所以如果用innerText设置一个值的时候,浏览器会触发回流操作,把整个页面重新渲染一遍。
相应的,textContent可能会触发重绘,比如你设置的textContent值由张三改为李四,这个div占据的面积未变,整个页面也没有排版,这时候既不会重绘也不会回流;若文本的长度,设置不一样的长度,那么只对小区域有影响,那么此时只会触发重绘,不会触发回流;若你设置的值再配上整个的显示的样式,对整个页面有影响了,那么这个时候就会触发回流。
<div>张三</div>
el.textContent = '李四'
相对来讲,textContent对浏览器性能的影响要比innerText小;
所以在对浏览器进行兼容性判断的时候,要先判断textContent,再去判断innerText
- innerText的返回值会被格式化,而textContent不会;
造成此区别的主因还是由于第一点,innerText依赖于页面的显示
比如现在为dom节点 div1设置值为’a\na’,本意是在页面中显示成a、换行、a,innerText依赖于页面的显示,这时候就会按照你写的方式把它展示出来,反映在页面中就是<div>a<br>a</div>
为另一个dom节点div2设置textContent为’a\na’,那么它会把这个值直接写在源码中,反映在页面中就是<div>a a</div>
<html lang="en">
<head>
<style>
div {
width: 300px;
margin-top: 10px;
border: 1px solid #eee;
padding: 5px;
}
</style>
</head>
<body>
<div id="div1"></div>
<div id="div2"></div>
</body>
<script>
const el = document.getElementById('div1')
el.innerText = 'a\n\na'
const el2 = document.getElementById('div2')
el2.textContent = `a\n\n\na`
</script>
</html>
效果:
5. 与 textContent 不同的是, 在 Internet Explorer (对于小于等于 IE11 的版本) 中对 innerText 进行修改, 不仅会移除当前元素的子节点,而且还会永久性地破坏所有后代文本节点(所以不可能再次将节点再次插入到任何其他元素或同一元素中)。
4. 与innerHTML的区别
正如其名称,innerHTML 返回 HTML 文本。通常,为了在元素中检索或写入文本,人们使用innerHTML。但是,textContent通常具有更好的性能,因为文本不会被解析为HTML。此外,使用textContent可以防止 XSS 攻击。
5. 归属区别
- textContent 是 Node 对象的属性;
- innerHTML 是 Element 对象的属性;
- innerText 是 HTMLElement 对象的属性;