在脚本标记文本属性 - 澄清? [英] Text property in script tags - Clarification?

查看:144
本文介绍了在脚本标记文本属性 - 澄清?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在阅读角的指示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

VAR 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

\r
\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 not textContent ? 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 contain Look at me! I am irrelevant!, while text 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 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('');
}

As you can see (and as the specification says and the example shows), only text nodes are handled when getting an element's text property, while textContent also throws into the mix the textContent of its element children.

innerText is a more complex beast which won't be explained in this answer; it's like a normalized textContent. You can read more about it in this fabulous blog post by Kagnax.

The Setter

Now let's talk about the setter. The specification says it should behave the same way as setting textContent, 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 setting text does, or that after injecting it into the page setting textContent has no effect but setting text does.

Testing on latest Chrome (47) and Firefox (43) shows that both interpretations are false: setting a textContent before injection works, and setting text 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 of text.

But I couldn't help but smile when I saw that IE was still alive and kickin'.

这篇关于在脚本标记文本属性 - 澄清?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆