textContent和innerText之间的区别

在JavaScript中,textContentinnerText有什么区别?

我可以像下面这样使用textContent吗?

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

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

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

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

innerText &textContent自2016年起标准化。所有Node对象(包括纯文本节点)都有textContent,但只有HTMLElement对象有innerText

虽然textContent适用于大多数浏览器,但它不适用于IE8或更早版本。使用这个填充只在IE8上工作。此填充将不能与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/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty

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

innerTexttextContent之间的关键区别在Kelly Norton的博文:innerText vs. 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/中的表(进一步阅读& # 39; innerText& # 39;可以在IE中运行,但不能在Firefox中运行)。
  3. 因此,innerText更加注重性能:它需要布局信息来返回结果。
  4. innerText仅为HTMLElement对象定义,而textContent为所有Node对象定义。

一定要看看这个答案下面的信息评论。

textContent在IE8-中不可用,裸金属填充看起来像一个在指定节点的所有childNodes上使用nodeValue的递归函数:

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

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 gives:

1
2
3
4 5 6 7 8

span.textContent给:

1234
5
6
7
8

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

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

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

你可以忘记所有让你困惑的要点,但要记住两件事:

  1. 当你试图修改文本时,textContent通常是你要寻找的属性。
  2. 当你试图从某个元素中抓取文本时,innerText近似于用户用光标高亮显示元素的内容,然后复制到剪贴板中所获得的文本。而textContent给出了所有可见或隐藏的元素,包括<script><style>元素。

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.

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

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

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

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

Firefox reports 3 and 2, Chrome reports 3 and 3.

Not sure yet if this is a bug (and if so, in which browser) or just one of those quirky incompatibilities which we have to live with.

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

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

document.querySelector('h1').innerText/innerHTML/textContent

.querySelector('h1').innerText -给我们里面的文本。它对当前正在显示的内容敏感,或者忽略正在隐藏的人员。

.querySelector('h1').textContent -它类似于innerText,但它并不关心显示的是什么或实际显示给用户的是什么。它会显示一切。

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