这是 jsbin 的一个分支,您可以在其中看到差异:http://jsbin.com/tovipiruce/1/edit?html,js,输出 http://jsbin.com/tovipiruce/1/edit?html,js,output
或者,如果您是片段粉丝:
var scriptElem = document.getElementById('a');
var child = document.createElement('b');
child.textContent = 'Look at me! I am irrelevant!';
var comment = document.createComment('I contain a lot of wisdom');
var justText = document.createTextNode('just your average text node');
scriptElem.appendChild(child);
scriptElem.appendChild(comment);
scriptElem.appendChild(justText);
console.log(scriptElem);
console.log('textContent:', scriptElem.textContent);
console.log('innerText:', scriptElem.innerText);
console.log('text:', scriptElem.text);
<!DOCTYPE html>
<html>
<body>
<p>Open your console</p>
<script id="a" type="blabla">
foo
<b>bar</b>
baz
</script>
</body>
</html>
这里最大的区别是子元素的处理方式:textContent
包括子元素,因此输出will包含Look at me! I am irrelevant!
, while text
will not.
我将在代码中重复一遍:
scriptElem.textContent.includes('Look at me!'); // true
scriptElem.text.includes('Look at me!'); // false
吸气剂
让我们看一下 getter 的一个非常幼稚的实现textContent
and text
:
function textContent(elem) {
return Array.from(elem.childNodes).map(node => {
// recurse into element nodes
if (node.type === Node.ELEMENT_NODE) {
return textContent(elem);
}
// return the value of text nodes
if (node.type === Node.TEXT_NODE) {
return node.nodeValue;
}
// and ignore everything else
return '';
}).join('');
}
function text(elem) {
return Array.from(elem.childNodes).map(node => {
// return the value of text nodes
if (node.type === Node.TEXT_NODE) {
return node.nodeValue;
}
// and ignore everything else
return '';
}).join('');
}
正如您所看到的(正如规范所述和示例所示),当get
给一个元素的text
财产,同时textContent
还加入了textContent
其元素子项。
innerText
是一个更复杂的野兽,在这个答案中不会解释;这就像一个标准化的textContent
。您可以阅读更多相关内容在 Kagnax 这篇精彩的博客文章中 http://perfectionkills.com/the-poor-misunderstood-innerText/.
二传手
现在我们来谈谈set
之三。规范说它的行为应该与设置相同textContent
,但是 mdn 说了以下奇怪的事情:
然而,与 textContent 属性不同的是,在将节点插入 DOM 后,该属性将被评估为可执行代码。
有两种方法可以解释这句话:要么设置脚本的textContent
在将其注入页面之前设置时没有效果text
确实如此,或者将其注入页面设置后textContent
没有任何效果,但设置text
does.
在最新的 Chrome (47) 和 Firefox (43) 上进行的测试表明,这两种解释都是错误的:设置textContent
注射工作之前和设置text
注射后没有效果。如果有人有一个 IE 并希望对此进行测试,如果您编辑此答案,我将不胜感激。
...但为什么?
我们已经了解了 setter 和 getter。现在让我们问为什么text
有用?这是一个悬而未决的问题。坦白说,我真的不知道。正如您在原始代码中所看到的,您不能只在脚本标记中插入标记,它不会被解析为 html。因此,看到差异的唯一方法是在脚本标记内动态注入节点。
I ran git blame
在该文件上,发现它来自这次提交 https://github.com/angular/angular.js/commit/94dd68570952f6f31abfa351b1159afcd3588a57:
修复(脚本):在 ie 上错误读取脚本文本
IE 以特殊方式处理脚本标签,.text() 不起作用。直接读取 .text 属性可以解决该问题。
添加的测试用例在脚本标记内进行绑定。我不知道角度,所以我不知道这意味着什么,我也没有 IE,所以我无法检查当你使用时测试用例中会发生什么textContent
代替text
.
但当我看到 IE 仍然活跃且活跃时,我忍不住笑了。