在脚本标记文本属性 - 澄清? [英] Text property in script tags - Clarification?
问题描述
在阅读角的指示code,我看到的 这个 :
VAR scriptDirective = ['$ templateCache',函数($ templateCache){
返回{
限制:'E',
终端:真实,
编译:功能(元素,属性){
如果(attr.type =='文/ NG-模板'){
VAR templateUrl = attr.id,
文=元素[0]的.text; //< - 看这里 $ templateCache.put(templateUrl,文字);
}
}
};
}];
但我不知道那是什么文本
属性(我的意思是 - ?为什么不使用的innerText)
有人告诉我说:
的这就像刚才的textContent只抓住元素中的文本节点,没有递归或者喜欢的
也期待在文档:
该IDL属性文字必须返回的内容串联
那些脚本元素对儿童的所有文本节点(忽略
任何其他节点,如评论或要素),按照树形结构顺序。上
设置时,必须采取行动的方式作为的textContent IDL属性相同。
块引用>不清楚我。
MDN的:
文本:像的textContent属性,该属性设置元素的文本内容。不像的textContent属性,但是,
这个属性被评估为可执行code后的节点
插入到DOM。
块引用>所以,我创建了一个的测试 :
<脚本ID =类型=布拉布拉>
富
< B>巴≤; / B>
巴兹
< / SCRIPT>
<脚本>
的console.log(的document.getElementById('A')。文)
的console.log(的document.getElementById('A')。的textContent)
< / SCRIPT>但两者显示的确切的内容:
富
< B>巴≤; / B>
巴兹问:
为什么角使用
文本
,而不是的textContent
?如果它是一个模板 - 那么他们就需要考虑标签....没有?有什么区别(在剧本的标签)
的innerText
/文字之间
/的textContent
?<子>
的 BTW也有类似<一个href=\"http://stackoverflow.com/questions/13172305/difference-between-text-and-textcontent-properties\">question这里,但它并没有过多谈论的剧本
范围(实际上是一个必须在我的问题)的解决方案这是你的jsbin的一个分支,在那里你可以看到其中的差别:的 http://jsbin.com/tovipiruce/1/edit?html,js,output
或者,如果你是一个球迷的片段:
\r\r\r\rVAR scriptElem =的document.getElementById('A');\r
\r
VAR孩子=使用document.createElement('B');\r
child.textContent ='看我的!我无关'!;\r
\r
VAR评论= document.createComment(我中含有大量的智慧);\r
VAR justText = document.createTextNode('只是你的普通文本节点');\r
\r
scriptElem.appendChild(小孩);\r
scriptElem.appendChild(注解);\r
scriptElem.appendChild(justText);\r
\r
的console.log(scriptElem);\r
的console.log('的textContent:',scriptElem.textContent);\r
的console.log('的innerText:',scriptElem.innerText);\r
的console.log('文字:',scriptElem.text);\r
&LT;!DOCTYPE HTML&GT;\r
&LT; HTML和GT;\r
&LT;身体GT;\r
\r
&LT; P&GT;打开控制台&LT; / P&GT;\r
\r
&LT;脚本ID =类型=布拉布拉&GT;\r
富\r
&LT; B&GT;巴≤; / B&GT;\r
巴兹\r
&LT; / SCRIPT&GT;\r
\r
&LT; /身体GT;\r
&LT; / HTML&GT;\r
在这里最大的区别是怎样的子元素的处理方式:
的textContent
包含的子元素,从而使输出的会包含看着我!我无关!
,而文本
不会我会重复,在code:
scriptElem.textContent.includes(看我的!'); //真
scriptElem.text.includes(看我的!'); //假吸气
让我们来看看一个很天真的干将实施
的textContent
和文本
:函数的textContent(ELEM){
返回Array.from(elem.childNodes).MAP(结点=&GT; {
//递归到元素节点
如果(node.type === Node.ELEMENT_NODE){
返回的textContent(ELEM);
} //返回文本节点的值
如果(node.type === Node.TEXT_NODE){
返回node.nodeValue;
} //而忽略其他一切
返回'';
})。加入('');
}功能文本(ELEM){
返回Array.from(elem.childNodes).MAP(结点=&GT; {
//返回文本节点的值
如果(node.type === Node.TEXT_NODE){
返回node.nodeValue;
} //而忽略其他一切
返回'';
})。加入('');
}正如你所看到的(并作为规范说和示例所示),只有文本节点的处理时,
GET
婷元素的文本
属性,而的textContent
也投到混合的textContent
它的子元素的。
的innerText
是一个比较复杂的野兽,不会在这个答案来解释;它就像一个标准化的的textContent
。你可以阅读更多关于它由Kagnax 这个神话般的博客文章。二传手
现在让我们来谈谈
设置
之三。该规范说,它应该表现同样的方式设置的textContent
,但MDN说下面离奇的事情:
不像的textContent属性,但是,这种属性是节点插入DOM后评估为可执行code。
块引用>这里有两种方式间preT这样一句话:要么设置脚本的
设置的textContent
之前将其注入的页面没有任何影响,同时设置文本
做,或者说,其注入的页面设置的textContent
有没有影响,但设置文本
一样。的textContent
注射作品之前,和设置<$:在最新的Chrome(47)和Firefox(43)表明,无论间pretations都是假的测试C $ C>文本注射后没有任何效果。如果有人有一个IE浏览器躺在身边,并希望测试这个,我倒是AP preciate如果编辑这个答案。
...但是为什么呢?
因此,我们已经通过setter和吸走了。现在,让我们问为什么是
文本
有用吗?这是一个悬而未决的问题。坦白说,我真的不知道。正如你在你原来的code看到的,你不能只是插入标记在脚本标记,它没有被解析为HTML。所以看到有差别的唯一方法是当你动态地注入一个脚本标签中的节点。我跑了
git的怪
在该文件上,看到它从的这个承诺:
修复(脚本):对,即错误地读脚本文本
IE浏览器处理与特殊方式的.text()不工作script标签。读的.text属性直接修复该问题。
块引用>增加的测试案例做了script标签内具有约束力。我不知道这样的角度,我不知道这就需要什么,我也不具有IE浏览器,所以我不能检查测试案例,当你使用会发生什么
的textContent
而不是文本
。不过,我忍不住微笑,当我看到,IE浏览器仍然活着,并在唱歌。
While reading angular's directives code , I saw this :
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); } } }; }];
But I didn't know what is that
text
property ( I mean — why not use innerText ?)I was told that :
"it's like textContent just only grabs the text nodes inside the element, no recursion or the likes"
Also looking at the docs :
The IDL attribute text must return a concatenation of the contents of all the Text nodes that are children of the script element (ignoring any other nodes such as comments or elements), in tree order. On setting, it must act the same way as the textContent IDL attribute.
Wasn't clear for me.
Mdn's :
text:Like the textContent attribute, this attribute sets the text content of the element. Unlike the textContent attribute, however, this attribute is evaluated as executable code after the node is inserted into the DOM.
So I created a test :
<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>
But both shows the exact content :
" foo <b>bar</b> baz "
Question:
Why does angular uses
text
and nottextContent
? if it's a template - then they do need to consider tags....no ?What is the difference (in script tags) between
innerText
/text
/textContent
?BTW there is a similar question here , but it doesn't talk much about the
script
scope (which is actually a must in my question)解决方案Here's a fork of your jsbin where you can see the difference: http://jsbin.com/tovipiruce/1/edit?html,js,output
Or, if you're a snippets fan:
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>
The Big Difference here is how child elements are handled:
textContent
includes the child elements, so that the output will containLook at me! I am irrelevant!
, whiletext
will not.I'll repeat that in code:
scriptElem.textContent.includes('Look at me!'); // true scriptElem.text.includes('Look at me!'); // false
The Getter
Let's look at a very naive implementing of the getters of
textContent
andtext
: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(''); }
As you can see (and as the specification says and the example shows), only text nodes are handled when
get
ting an element'stext
property, whiletextContent
also throws into the mix thetextContent
of its element children.
innerText
is a more complex beast which won't be explained in this answer; it's like a normalizedtextContent
. You can read more about it in this fabulous blog post by Kagnax.The Setter
Now let's talk about the
set
ter. The specification says it should behave the same way as settingtextContent
, but mdn says the following bizarre thing:Unlike the textContent attribute, however, this attribute is evaluated as executable code after the node is inserted into the DOM.
There're two ways to interpret this sentence: Either that setting a script's
textContent
before injecting it into the page has no effect while settingtext
does, or that after injecting it into the page settingtextContent
has no effect but settingtext
does.Testing on latest Chrome (47) and Firefox (43) shows that both interpretations are false: setting a
textContent
before injection works, and settingtext
after injection has no effect. If someone has an IE lying around and wishes to test this, I'd appreciate if you edit this answer....but why?
So we've gone through the setter and the getter. Now let's ask why is
text
useful? That's an open question. Frankly, I don't really know. As you've seen in your original code, you can't just insert markup in a script tag, it's not parsed as html. So the only way to see a difference is when you dynamically inject nodes inside a script tag.I ran
git blame
on that file, and saw that it came from this commit:fix(script): Incorrectly reading script text on ie
IE deals with script tags in special way and .text() does not work. Reading the .text property directly fixes the issue.
The added test case does a binding inside the script tag. I don't know angular so I don't know what that entails, nor do I have IE so I can't check what happens in the test case when you use
textContent
instead oftext
.But I couldn't help but smile when I saw that IE was still alive and kickin'.
这篇关于在脚本标记文本属性 - 澄清?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!