textContent vs innerText

Node类型的innerText属性和textContent属性可谓相爱相杀,作为最早被IE引入的innerText属性虽然被广泛使用,但是在2016年前一直是非标准属性,直到2016年才被HTML标准正式指定。

Node类型的innerText属性和textContent属性十分类似,但还是有所不同:

  1. textContent会返回所有元素的非标签内容,其中包括<style>标签和<script>标签,但innerText不会返回这两个标签的内容。
  2. textContent会返回被隐藏的子代元素的内容,但innerText不会。
  3. innerText受CSS样式影响(参见第二点可能于此有关),MDN上说“it will trigger a reflow”,即触发重排(reflow),但textContent不会,这样会导致innerText的性能比textContent低。

在一篇国外Blog(http://kellegous.com/j/2013/02/27/innertext-vs-textcontent/)中提到一个例子:

<div id="t"><div>lions,
tigers</div><div style="visibility:hidden">and bears</div></div>

用textContent实际上会输出

用innerText会输出

你看,textContent会保留换行符并且将隐藏的子代元素的文本内容也显示出来,然而innerText则不会保留换行符(其实是以一个空格代替)以及不会显示隐藏的自带元素的文本内容。另外说到这个,还有一点需要说明的是innerText跟布局系统是息息相关的(这一点跟textContent有很大不同),比如还是刚才的例子,我改了一下:

<div id="t"><div>lions,tigers</div><div>and bears</div></div>

注意id为“t”的元素的两个子元素为块级元素,innerText输出为:

两个块级元素的文本各占一行(块级元素的feature),

但如果两个子元素为内联元素呢:

<div id="t"><span>lions,tigers</span><span>and bears</span></div>

这里我把两个div改成span元素,输出如下:

看!两个内联元素的文本在同一行(内联元素的feature)。

再来看看textContent,还是刚才的例子:

<div id="t"><div>lions,tigers</div><div>and bears</div></div>

textContent输出如下:

看!即使两个子元素都为块级元素,输出文本依然在同一行,除非两个块级子元素写在两行。内联元素也是同理,除非两个内联子元素写在两行,否则还是输出在同一行(这里就不赘述了,有兴趣的同学可以自行实验内联元素版本的)。

可见,innerText与textContent最大的不同就是innetText会考虑布局系统(其中包括考虑是否为块级元素还是内联元素)。

innerText会影响性能,因为它需要一些来自布局系统(CSS)的信息来考虑怎样将文本呈现给用户,我这里做一个性能测试(Firefox 58.0.2):

这里要重新渲染一个列表:

<ul class="list">
      <li>first</li>
      <li>second</li>
      <li>third</li>
      <li>forth</li>
      <li>fifth</li>
      <li>sixth</li>
      <li>seven</li>
      <li>eight</li>
      <li>nine</li>
      <li>ten</li>
      <li>eleven</li>
      <li>twelve</li>
      <li>thirteen</li>
      <li>fourteen</li>
      <li>fifteen</li>
      <li>sixteen</li>
      <li>seventeen</li>
      <li>eighteen</li>
      <li>nineteen</li>
      <li>twenty</li>
</ul>

JavaScript代码:

var ul=document.getElementsByClassName("list")[0];  // 获取列表

// innerText渲染时间测试
console.time("innerText");
for(var i=0;i<ul.childElementCount;i+=1){
    ul.children[i].innerText="innerText";
}
console.timeEnd("innerText");

// textContent渲染时间测试
console.time("textContent");
for(var j=0;j<ul.childElementCount;j+=1){
    ul.children[j].textContent="textContent";
}
console.timeEnd("textContent");

这是我随机获取的渲染时间数据:

测试1:

测试2:

测试3:

测试4:

测试5:

测试6:

由以上实验可知innerText的确有很大的性能问题,但时至今日依然会有很多人把innerText作为textContent的替代方案,你能在很多js库看到 node.textContent||node.innerText 的身影,这确实带来了很多性能问题,现在推荐使用的是textContent。

原文地址:https://www.cnblogs.com/linweinb/p/8440446.html