textContent 与 innerText 之间的区别

Difference between textContent vs innerText

提问人:J K 提问时间:2/5/2016 最后编辑:u-waysJ K 更新时间:11/30/2022 访问量:163455

问:

JavaScript 和 有什么区别?textContentinnerText

我可以使用以下方法吗:textContent

var logo$ = document.getElementsByClassName('logo')[0];
logo$.textContent = "Example";
JavaScript的

评论

1赞 Yehia Awad 2/5/2016
@Pointy所有浏览器都支持什么?
14赞 webketje 2/5/2016
一篇关于它的好博客文章
0赞 Pointy 2/5/2016
没有一个。您必须包含代码来检查存在哪些代码,然后使用该代码。
9赞 webketje 2/5/2016
@Pointy请参阅我指出的博客文章。你的陈述不正确,是有区别的。
11赞 Armen Michaeli 4/27/2019
innerText并且绝对不一样。节点内容中出现的空格将导致这两个属性产生不同的内容,元素和其他块级呈现的后代的出现也是如此。textContentbr

答:

8赞 Jeremy Ray Brown 2/5/2016 #1

大多数浏览器都支持 textContent。ie8 或更早版本不支持它,但可以使用 polyfill

textContent 属性设置或返回指定节点的文本内容及其所有后代。

查看 http://www.w3schools.com/jsref/prop_node_textcontent.asp

28赞 Richard Hamilton 2/5/2016 #2

从2016年开始,innerTexttextContent都是标准化的。所有对象(包括纯文本节点)都有 ,但只有对象有 。NodetextContentHTMLElementinnerText

虽然适用于大多数浏览器,但它不适用于 IE8 或更早版本。使用此 polyfill 使其仅在 IE8 上工作。此 polyfill 不适用于 IE7 或更早版本。textContent

if (Object.defineProperty 
  && Object.getOwnPropertyDescriptor 
  && Object.getOwnPropertyDescriptor(Element.prototype, "textContent") 
  && !Object.getOwnPropertyDescriptor(Element.prototype, "textContent").get) {
  (function() {
    var innerText = Object.getOwnPropertyDescriptor(Element.prototype, "innerText");
    Object.defineProperty(Element.prototype, "textContent",
     {
       get: function() {
         return innerText.get.call(this);
       },
       set: function(s) {
         return innerText.set.call(this, s);
       }
     }
   );
  })();
}

该方法在 IE9 或更高版本中可用,但在 IE8 中仅适用于 DOM 对象。Object.defineProperty

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent

评论

2赞 geekonaut 2/5/2016
这也是它的规格: w3.org/TR/DOM-Level-3-Core/core.html 此外,(非常旧的)浏览器支持表(webdevout.net/browser-support-dom#dom3core)也表明,它支持IE9+,因此对于IE8及更早版本,它是你的朋友。innerText
0赞 Richard Hamilton 2/5/2016
实际上,最好不支持 ie8 或使用 polyfill。我在帖子中发布了 polyfill
1赞 Pointy 2/5/2016
当它不支持 IE8 时,polyfill 如何在 IE8 中工作?Object.defineProperty()
2赞 caub 1/18/2018
你为什么不更新你的答案?html.spec.whatwg.org/multipage/......
3赞 the chad 5/3/2019
这是 MDN 关于 innerText 的一句话——“这个功能最初是由 Internet Explorer 引入的,在被所有主要浏览器供应商采用后,于 2016 年在 HTML 标准中正式指定。
474赞 webketje 2/5/2016 #3

Kelly Norton 的博文很好地概述了 和 之间的主要区别:innerText 与 textContent。您可以在下面找到摘要:innerTexttextContent

  1. innerText是非标准的,是较早标准化的。textContent
  2. innerText返回节点中包含的可见文本,同时返回文。例如,在以下 HTML 中,将返回 'Hello',而 将返回 'Hello World'。有关更完整的差异列表,请参阅 http://perfectionkills.com/the-poor-misunderstood-innerText/ 中的表格(进一步阅读“innerText”在IE中有效,但在Firefox中无效)。textContent<span>Hello <span style="display: none;">World</span></span>innerTexttextContent
  3. 因此,它对性能的要求要高得多:它需要布局信息来返回结果。innerText
  4. innerText 仅针对对象定义,而 textContent 针对所有对象定义。HTMLElementNode

请务必查看此答案下方的信息性评论。

textContent在 IE8- 中不可用,并且裸机 polyfill 看起来像在所有指定节点上使用的递归函数:nodeValuechildNodes

function textContent(rootNode) {
  if ('textContent' in document.createTextNode(''))
    return rootNode.textContent;

  var childNodes = rootNode.childNodes,
      len = childNodes.length,
      result = '';
  
  for (var i = 0; i < len; i++) {
    if (childNodes[i].nodeType === 3)
      result += childNodes[i].nodeValue;
    else if (childNodes[i].nodeType === 1) 
      result += textContent(childNodes[i]);
  }

  return result;
}

评论

75赞 Jelle De Loecker 3/15/2018
还值得注意的是:会将元素转换为换行符,而会忽略它们。因此,当使用innerText<br>textContent<br>textContent
25赞 Franklin Yu 2/28/2019
那么使用二传手有什么区别吗?像 v.s.elem.textContent = 'foobar'elem.innerText = 'foobar'
16赞 Kobi 12/16/2019
和 之间的另一个行为区别是:如果通过 CSS 更改元素,则会影响 'innerText' 的结果,但不会影响 .例如:of 将是“HELLO WORLD”,而将是“Hello World”。innerTexttextContenttext-transformtextContentinnerText<div style="text-transform: uppercase;">Hello World</div>textContent
1赞 Shimon S 10/12/2020
关于“3”点(性能)。我做了一个快速测试,我看不出这是真的。 在控制台中执行它并查看。在某些情况下(例如,在这个网站上),textContent mail.google.com 会好一点 - 反之亦然。let allElements = [...document.getElementsByTagName('*')]; t1 = performance.now(); for(let i=0; i<allElements.length; i++){ txt = allElements[i].innerText; } t2 = performance.now(); console.log('innerText', t2-t1); for(let i=0; i<allElements.length; i++){ txt = allElements[i].textContent; } t3 = performance.now(); console.log('textContent', t3-t2);
4赞 webketje 10/13/2020
@ShimonS innerText 的性能要重得多,但这是相对的:如果比平均速度慢 100 倍,并且每次操作需要 1/1000 毫秒,那么 1/10 毫秒对人类来说仍然会感觉很快。此外,两者之间有意义的比较只能是元素包含许多隐藏的东西,例如或子元素innerTexttextContenttextContent<script>style="display: none;"
58赞 Martin Wantke 2/27/2018 #4

textContent是唯一可用于文本节点的节点:

var text = document.createTextNode('text');

console.log(text.innerText);    //  undefined
console.log(text.textContent);  //  text

在元素节点中,计算元素,同时计算控制字符:innerText<br>textContent

var span = document.querySelector('span');
span.innerHTML = "1<br>2<br>3<br>4\n5\n6\n7\n8";
console.log(span.innerText); // breaks in first half
console.log(span.textContent); // breaks in second half
<span></span>

span.innerText给:

1
2
3
4 5 6 7 8

span.textContent给:

1234
5
6
7
8

如果内容设置为 ,则带有控制字符的字符串(例如换行符)不适用于 。反之(设置控制字符 ),所有字符都返回 和 :textContentinnerTexttextContentinnerTexttextContent

var div = document.createElement('div');
div.innerText = "x\ny";
console.log(div.textContent);  //  xy

46赞 Northern 5/18/2018 #5

对于那些在谷歌上搜索这个问题并到达这里的人。我觉得这个问题最明确的答案是在 MDN 文档中:https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent

您可以忘记所有可能让您感到困惑的要点,但请记住两件事:

  1. 当您尝试更改文本时,通常是您要查找的属性。textContent
  2. 当您尝试从某个元素中抓取文本时,近似于用户在用光标突出显示元素的内容,然后复制到剪贴板时将获得的文本。并为您提供所有可见或隐藏的内容,包括元素。innerTexttextContent<script><style>

评论

0赞 EGurelli 9/27/2021
“此外,由于 innerText 考虑了 CSS 样式,因此读取 innerText 的值会触发重排以确保最新的计算样式。(回流焊的计算成本可能很高,因此应尽可能避免。当浏览器必须再次处理和绘制部分或全部网页时,例如在交互式站点上更新之后,就会发生重排。developer.mozilla.org/en-US/docs/Glossary/Reflow innerText <-> ReFlow 关系。这些 MDN 文章比其他答案更具解释性。
1赞 Sebastian 3/25/2023
@Northern从您提供的 MDN 链接中,我无法确定 setter 的任何差异,而只能确定 getter 的差异。至少当两者都存在时。你同意吗?
5赞 Milan Chandro 7/21/2019 #6

textContent返回全文,不关心可见性,而确实如此。innerText

<p id="source">
    <style>#source { color: red; }</style>
    Text with breaking<br>point.
    <span style="display:none">HIDDEN TEXT</span>
</p>

输出:textContent

#source { color: red; } Text with breakingpoint. HIDDEN TEXT

输出 ( 注意 如何 知道 标签 ,并忽略隐藏元素 ):innerTextinnerText<br>

Text with breaking point.

评论

1赞 Sebastian 10/4/2019
在 IE11 中,innerText 的行为与 textContent 的行为相同。
-3赞 Ashwath Halemane 12/19/2019 #7

innerHTML 甚至会执行 HTML 标签,这可能会造成任何类型的客户端注入攻击,例如基于 DOM 的 XSS。 下面是代码片段:

<!DOCTYPE html>
<html>
    <body>
        <script>
            var source = "Hello " + decodeURIComponent("<h1>Text inside gets executed as h1 tag HTML is evaluated</h1>");  //Source
            var divElement = document.createElement("div");
            divElement.innerHTML = source;  //Sink
            document.body.appendChild(divElement);
        </script>
    </body>
</html>

如果使用 .textContent,则不会计算 HTML 标记并将其打印为 String。

<!DOCTYPE html>
<html>
    <body>
        <script>
            var source = "Hello " + decodeURIComponent("<h1>Text inside will not get executed as HTML</h1>");  //Source
            var divElement = document.createElement("div");
            divElement.textContent = source;  //Sink
            document.body.appendChild(divElement);
        </script>
    </body>
</html>

编号: https://www.scip.ch/en/?labs.20171214

评论

2赞 AndrewF 9/9/2020
问题没有提到.答案没有提到.innerHTMLinnerText
7赞 Mr Lister 2/1/2020 #8

除了其他答案中提到的所有差异之外,这是我最近才发现的另一个差异:

尽管据说该属性自 2016 年以来已经标准化,但它在浏览器之间表现出差异:Mozilla 忽略了 U+200E 和 U+200F 字符(“lrm”和“rlm”),而 Chrome 则没有。innerTextinnerText

console.log(document.getElementById('test').textContent.length);
console.log(document.getElementById('test').innerText.length);
<div id="test">[&#x200E;]</div>

Firefox 报告 3 和 2,Chrome 报告 3 和 3。

还不确定这是一个错误(如果是这样,在哪个浏览器中)还是只是我们必须忍受的那些古怪的不兼容问题之一。

评论

3赞 Roko C. Buljan 9/11/2021
哇。令人惊讶的是!
1赞 baptx 6/17/2021 #9

与此相比的另一个有用行为是换行符和彼此相邻的多个空格将仅显示为一个空格,这样可以更容易地比较字符串。innerTexttextContent

但取决于你想要什么,可能就足够了。firstChild.nodeValue

0赞 vitoboski 7/3/2021 #10
document.querySelector('h1').innerText/innerHTML/textContent 

.querySelector('h1').innerText- 给我们里面的文字。它对当前显示的内容或隐藏的员工敏感,将被忽略。

.querySelector('h1').textContent- 就像,但它不关心正在显示的内容或实际向用户显示的内容。它将显示所有内容。innerText

.querySelector('h1').innerHTML = <i>sdsd</i>将起作用* - 检索完整内容,包括标记名称。

评论

0赞 m4n0 10/17/2021
有 innertextContent 吗?
0赞 CennoxX 4/6/2022
@m4n0不,我已经纠正了答案