先记住这个答案
textContent 返回所有后代文本,不感知样式,因此隐藏元素也会包含;innerText 仅返回渲染可见文本,读取会触发重排;innerHTML 返回或设置 HTML 字符串,设置时解析字符串。设置纯文本应使用 textContent,避免解析风险。
- textContent 不解析 HTML,返回纯文本
- innerText 触发重排且忽略隐藏文本
- innerHTML 解析字符串,适合 HTML 片段
三种属性的底层差异
textContent 是 Node 接口的属性,会串联所有后代节点中的文本节点,并忽略注释。它不感知样式,因此即使元素被 display:none 隐藏或包含在 <script> 标签中,其文本也会被读出。设置 textContent 会删除现有子节点,替换为单个文本节点,一般适合写入纯文本内容。
innerText 定义在 HTMLElement 上,近似于用户“看见”的文字。读取 innerText 时,浏览器会计算样式与布局,以判断哪些文本是可见的,因此隐藏元素的文本不会出现在结果中,并且换行和间距会被规范化。这一计算过程会触发强制同步回流(layout thrashing),所以频繁读取性能较差。
innerHTML 返回元素内部的 HTML 序列化字符串,设置时会先销毁现有子树,再将字符串交给 HTML 解析器,生成新的节点。字符串中的标签会被解释为元素而非普通字符,因此若包含不可信输入,可能注入脚本。读取 innerHTML 只生成序列化快照,不影响 DOM;设置 innerHTML 会整体重建内部节点,导致原有子节点上绑定的事件监听器一并丢失。
统计可见字数选错属性导致误差
场景:为一个可编辑区域实现“实时字数统计”,需求是统计用户当前能看到的字符数。若用 textContent 统计,会包含通过 CSS 折叠或隐藏的说明文本,导致计数远大于屏幕实际内容。改用 innerText 后,计数虽准确,但每次按键读取都会强制触发 reflow,输入出现明显卡顿。
处理:维护一个缓存变量,使用 MutationObserver 监听内容变化,只在变化后暂停下一帧读取一次 innerText,并在 requestAnimationFrame 中更新 UI。这样既避免了重复同步布局,又保证了统计的文本与用户所见一致。结果:字数正确,输入流畅,两次更新间无多余重排。
这些属性的适用范围与失效条件
textContent 在 Document 或 DocumentType 节点上返回 null,因此不能用它直接获取整页文本,正确做法是访问 document.documentElement.textContent。另外,如果目标节点是注释或 CDATA 节点,textContent 返回 nodeValue,但常规元素行为一致。当需要保留标签结构时,textContent 无法替代 cloneNode 或 innerHTML。
innerText 的输出依赖浏览器最新的样式和布局,当元素处于 display:none、Shadow DOM 或隐藏的 iframe 中时,innerText 可能返回空字符串。此外,它每次读取都会触发 reflow,在滚动或高频回调中使用容易造成性能问题。innerHTML 在设置时会全量重建 DOM,可能中断正在进行的动画或焦点状态,且不适合用作节点比较的基准。
容易答错的地方
- 混淆 textContent 和 innerText
- 误认为两者等价。innerText 感知 CSS,会过滤隐藏元素且触发重排,而 textContent 不关心样式,始终返回所有后代文本。例如
display:none的元素,textContent 能取得内容,innerText 返回空。 - 用 innerHTML 设置纯文本
- 直接使用 innerHTML 注入用户输入,字符串内含
<或>会被解析为标签导致 DOM 意外变化。正确做法是用 textContent 赋值,或者转义字符串后再交给 innerHTML,但后者容易遗漏边界。
面试官还会怎么问?
textContent 会返回 <script> 标签内的内容吗?
会。textContent 连接所有后代文本节点,包括 <script> 和 <style>,而 innerText 不会,因为脚本和样式内容不被渲染为可见文本。
读取 innerHTML 是否触发重排?
不会。innerHTML 只负责序列化 DOM,不读取布局信息。但设置 innerHTML 会销毁和重建节点,可能引发后续的样式与布局计算。
设置 textContent 后原来的子节点去到哪里?
会被直接从文档中移除,并替换为一个文本节点。若子元素上绑定事件,监听器也会被回收,除非外部有引用,否则无法恢复。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。