textContent与innerText之间的区别


156

textContent和之间有什么区别innerText

我可以使用textContent以下方法:

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

3
它们是相同的,但是某些浏览器支持一个,而另一些则支持。
尖尖的2016年

@Pointy所有浏览器都支持什么?
Yehia Awad '02


4
@Pointy请参阅我指向的博客文章。您的陈述不正确,有所不同。
Tyblitz '16

3
innerText而且textContent绝对不一样。节点内容中出现空白会导致两个属性产生不同的内容,因此br元素和其他块级渲染后代的出现也会如此。
AMN

Answers:


211

没有其他答案可以提供完整的解释,因此没有一个。innerText和之间的主要区别textContentKelly Norton的博客中很好地概述了:innerText与textContent。您可以在下面找到摘要:

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

textContentIE8中的一种解决方法将涉及nodeValue在所有childNodes指定节点上使用递归函数,这是尝试使用polyfill 的方法:

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;
}

16
同样值得注意的是:innerText会将<br>元素转换为换行符,而textContent忽略它们。因此<br>,使用时将串联两个只有一个元素(且没有空格)的textContent
单词

5
那么使用二传手时有什么区别吗?Like elem.textContent = 'foobar'vselem.innerText = 'foobar'
Franklin Yu

1
innerText和之间的另一个行为差异textContent:如果text-transform通过CSS 更改元素的,则将影响'innerText'的结果,但不会影响的结果textContent。例如: innerTextof <div style="text-transform: uppercase;">Hello World</div>将是“ HELLO WORLD”,而textContent将是“ Hello World”。
科比

25

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

textContent如果内容设置为,则带有控制字符的字符串(例如换行符)不可用innerText。另一种方法(用设置控制字符textContent),所有字符都用innerText和返回textContent

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


20

两者innerTexttextContent都从2016年开始标准化。所有Node对象(包括纯文本节点)都具有textContent,但是只有HTMLElement对象具有innerText

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

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);
       }
     }
   );
  })();
}

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

https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

https://developer.mozilla.org/zh-CN/docs/Web/API/Node/textContent


2
这也是它的规范:w3.org/TR/DOM-Level-3-Core/core.html 而且(很旧的)浏览器支持表(webdevout.net/browser-support-dom#dom3core)暗示, IE9 +支持此功能,因此对于IE8及更高版本,innerText是您的朋友。
geekonaut 2016年

实际上,最好是不支持ie8或使用polyfill。我在自己的帖子中发布了polyfill
Richard Hamilton

1
不支持IE8的polyfill如何工作Object.defineProperty()
尖尖的2016年

2
您为什么不更新答案?html.spec.whatwg.org/multipage/…–
caub

3
这是MDN关于innerText的引文-“此功能最初是由Internet Explorer引入的,并在所有主要浏览器供应商都采用后于2016年在HTML标准中正式指定。”
乍得

15

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

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

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


0

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

innerText的输出(请注意innerText如何识别诸如的标记<br>,并忽略隐藏的元素):

Text with breaking point.

在IE11中,innerText的行为与textContent的行为相同。
塞巴斯蒂安

0

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

即使该innerText属性自2016年以来就已标准化,但在浏览器之间仍存在差异:Mozilla会忽略中的U + 200E和U + 200F字符(“ lrm”和“ rlm”)innerText,而Chrome不会。

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。

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


-1

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.