脚本标记中的Text属性-澄清
Text property in script tags - Clarification?
在读取angular的指令代码时,我看到这个:
var scriptDirective = ['$templateCache', function($templateCache) {
return {
restrict: 'E',
terminal: true,
compile: function(element, attr) {
if (attr.type == 'text/ng-template') {
var templateUrl = attr.id,
text = element[0].text;// <-- Look here
$templateCache.put(templateUrl, text);
}
}
};
}];
但我不知道text
属性是什么(我的意思是——为什么不使用innerText?)
有人告诉我:
"这就像textContent只抓取元素内部的文本节点,没有递归或类似的东西"
同时查看文档:
IDL属性文本必须返回的内容的串联作为script元素子级的所有Text节点(忽略诸如注释或元素之类的任何其他节点)。在…上设置,它必须以与textContent IDL属性相同的方式操作。
我还不清楚。
马里兰州:
text:与textContent属性一样,该属性设置元素的文本内容。然而与textContent属性不同,在节点被插入到DOM中。
所以我创建了一个测试:
<script id="a" type="blabla">
foo
<b>bar</b>
baz
</script>
<script >
console.log(document.getElementById('a').text)
console.log(document.getElementById('a').textContent)
</script>
但两者都显示了精确的内容:
"
foo
<b>bar</b>
baz
"
问题:
为什么angular使用
text
而不使用textContent
?如果这是一个模板,那么他们确实需要考虑标签。。。。不innerText
/text
/textContent
之间(在脚本标记中)有什么区别?
顺便说一句,这里也有一个类似的问题,但它没有太多地谈论script
范围(这实际上是我问题中的必选项)
这里是jsbin的一个分支,您可以在其中看到差异:http://jsbin.com/tovipiruce/1/edit?html,js,输出
或者,如果你是一个片段爱好者:
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
包括子元素,因此输出将包含Look at me! I am irrelevant!
,而text
不会。
我将在代码中重复一遍:
scriptElem.textContent.includes('Look at me!'); // true
scriptElem.text.includes('Look at me!'); // false
Getter
让我们来看看textContent
和text
的getter的一个非常天真的实现:
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
放入混合中。
CCD_ 17是一个更复杂的野兽,在这个答案中不会解释;它就像一个标准化的CCD_ 18。你可以在Kagnax的这篇精彩的博客文章中阅读更多关于它的信息。
The Setter
现在让我们来谈谈set
ter。规范说它应该以与设置textContent
相同的方式进行操作,但mdn说了以下奇怪的事情:
然而,与textContent属性不同的是,在将节点插入DOM后,该属性将被评估为可执行代码。
有两种方法可以解释这句话:要么在将脚本的textContent
注入页面之前设置它没有效果,而设置text
有效果,要么在将其注入页面之后设置textContent
没有效果,但设置text
有效果。
在最新的Chrome(47)和Firefox(43)上测试表明,这两种解释都是错误的:在注入前设置textContent
有效,在注入后设置text
无效。如果有人有一个IE,并希望测试这个,如果你编辑这个答案,我将不胜感激。
。。。但为什么呢
所以我们已经经历了二传手和接球手。现在让我们来问一下text
为什么有用?这是一个悬而未决的问题。坦率地说,我真的不知道。正如您在原始代码中所看到的,您不能只在脚本标记中插入标记,它不会被解析为html。因此,查看差异的唯一方法是在脚本标记中动态注入节点。
我在那个文件上运行了git blame
,发现它来自这个提交:
修复(脚本):错误地读取ie 上的脚本文本
IE以特殊的方式处理脚本标记,.text()不起作用。读取.text属性可以直接修复此问题。
添加的测试用例在脚本标记内部进行绑定。我不知道angular,所以我不知道这意味着什么,我也没有IE,所以当你使用textContent
而不是text
时,我无法检查测试用例中发生了什么。
但当我看到IE还活着并开始工作时,我忍不住笑了。
- RegEx删除空属性?例如,如果(class=“”||class=“”)移除;否则就下课
- 全局变量和全局对象的属性之间有什么区别吗
- 如果使用 lodash 将属性存在于另一个对象中,则向对象添加属性
- 如何在Bootstrap Modal中为动态点击生成的变量设置jade属性
- 序列化数据属性中对象的最可靠方法
- 分析高度属性时出现意外值{{specs.height}}.index.html
- TypeError:无法读取属性'推'未定义的JavaScript
- 同样,同样的错误'ahorcado.js:26未捕获类型错误:无法读取属性'beginPath'
- AngularJS-使用'true'属性
- 可以't使用JavaScript获取width属性
- 未捕获的TypeError无法读取未定义的属性socialsharing
- 如何使用javascript获取嵌套对象中所有子对象的单个属性
- JavaScript Pub/Sub属性访问问题
- 从JavaScript访问struts操作中的属性
- 是否可以从父类访问子类的属性
- 如何更改reactjs中外部/独立组件的状态或属性
- 如何在选项卡上定义属性'的主窗口对象
- 锚点元素的href属性自动更改
- 脚本标记中的Text属性-澄清
- 在使用Html5 getter和setter实现带有揭示模块模式的属性时,需要澄清