脚本标签中的文本属性 - 澄清?

2024-03-11

在阅读 Angular 的指令代码时,我看到this https://github.com/angular/angular.js/blob/master/src/ng/directive/script.js#L43 :

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 只是抓取元素内的文本节点,没有递归或类似的”

还关注docs https://html.spec.whatwg.org/multipage/scripting.html#dom-script-text :

IDL 属性文本必须返回以下内容的串联 作为脚本元素子元素的所有文本节点(忽略 任何其他节点(例如注释或元素),按树顺序。在 设置,它的行为方式必须与 textContent IDL 属性相同。

我不清楚。

Mdn's https://developer.mozilla.org/en/docs/Web/HTML/Element/script#attr-text :

text:与textContent属性一样,该属性设置元素的文本内容。然而,与 textContent 属性不同的是, 该属性在节点被评估后被评估为可执行代码 插入到 DOM 中。

所以我创建了一个test http://jsbin.com/xateyatako/1/edit?html,console :

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

但两者都表明exact内容 :

"
 foo
   <b>bar</b>
   baz
"

问题:

  • 为什么使用角度text并不是textContent?如果它是一个模板 - 那么他们确实需要考虑标签......不是吗?

  • 有什么区别(在script标签)之间innerText/text/textContent ?

BTW there is a similar question here https://stackoverflow.com/questions/13172305/difference-between-text-and-textcontent-properties , but it doesn't talk much about the script scope (which is actually a must in my question)


这是 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 仍然活跃且活跃时,我忍不住笑了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

脚本标签中的文本属性 - 澄清? 的相关文章

随机推荐

  • Ruby:读取 PDF 文件

    我正在寻找一种快速可靠的方法来在 Ruby 在 Linux 和 OSX 上 中读取 解析大型 PDF 文件 直到现在我发现了相当古老和简单的PDF 工具包 http pdf toolkit rubyforge org a pdf转文本 ht
  • ASP.NET 5 Web 应用程序作为 Azure Web 角色?

    我们的解决方案中有一个 ASP NET 5 Web 应用程序 通常 我们可以右键单击云服务 角色 项 然后从解决方案中的现有项目添加新角色 但它无法将该项目标识为 Web 角色 我们如何能够在 Azure Web 角色中托管 ASP NET
  • 生成位置周围的随机坐标

    我想要一个函数 它接受地理位置 纬度 经度 并生成周围的随机坐标集 但也将这些参数作为计算的一部分 要制作的随机坐标数 生成半径 随机坐标之间的最小距离 以米为单位 用于生成其周围位置的根坐标 生成方式的示例 实现这一目标的好方法是什么 生
  • 使用环境变量的 Maven 本地存储库

    如何使用环境用户变量设置 标记 我尝试了这条路 myRepo repo 但它不起作用 myRepo C maven repo 我无法使用绝对路径来解决可移植性问题 但我可以将 myRepo 设置到每个系统上的正确位置 其中绝对路径可能会有所
  • 我可以在本地测试 AWS Glue 代码吗?

    阅读 Amazon 文档后 我的理解是运行 测试 Glue 脚本的唯一方法是将其部署到开发端点并在必要时进行远程调试 同时 如果 Python 代码由多个文件和包组成 则除了主脚本之外的所有文件和包都需要压缩 这一切让我感觉 Glue 不适
  • 如何使用与其文件扩展名关联的程序打开文件?

    有没有一种简单的方法可以在Windows中通过其关联程序打开文件 就像在 Windows 资源管理器中双击它一样 但使用我的代码自动完成 例如 在计算机 A 上 text txt 将在写字板中打开 但在计算机 B 上 由于用户文件扩展名分配
  • Bootstrap - 选择和按钮彼此相邻

    我有一个
  • 我应该如何编写 .i 文件来包装 Java 或 C# 中的回调

    我的 C 程序使用定期调用的回调函数 我希望能够处理 Java 或 C 程序中的回调函数 我应该如何编写 i 文件来实现此目的 C 回调看起来像这样 static void on incoming call pjsua acc id acc
  • JDBI 的 @BindBean 在 INSERT 期间未在 bean 类中找到命名参数

    当使用 JDBI 的 BindBean 将值插入 Dropwizard 中的 Mysql 数据库时 我始终遇到以下异常 问题似乎是 JDBI 无法找到 bean 中的属性 我已经将该问题隔离到一个单独的项目中 但无法弄清楚哪里出了问题 我将
  • 在 HTML 上使用 setter 和 getter 变量(角度组件)

    我创建了一个简单的角度组件来测试使用 getter setter 样式的变量的使用情况 import Component from angular core Component selector my app templateUrl app
  • 仅隐藏滚动上的操作栏而不是操作栏选项卡

    我在向下滚动时尝试隐藏操作栏时遇到问题 然后在向上滚动时 必须再次显示操作栏 For Eg 我提到了这个Tutorial http www techrepublic com article pro tip maximize android
  • Android 12 上的 PendingIntent.FLAG_UPDATE_CURRENT 错误

    在我的应用程序中 我计划在每天的特定时间设置闹钟 为此 我正在使用警报管理器 请参阅下面的代码 这在 12 以下的 Android 设备上运行良好 但在 12 及更高版本上则不行 Firebase Crashlytics 上出现错误 以 S
  • 如何用CGPathAddCurveToPoint创建一个完美的半圆?

    我正在尝试使用 CGPathAddCurveToPoint 创建一个半径为 15 点的完美右半圆 如下所示 CGPathMoveToPoint path NULL 0 0 CGPathAddCurveToPoint path NULL 15
  • Google Chrome 扩展程序可在用户点击后关闭通知

    Chrome 扩展程序运行良好 我的问题是通知会在 7 秒后关闭 我想让用户点击关闭通知 function engine var latestId var ids var messages var newmessage get http l
  • git merge:将更改应用于移动到不同文件的代码

    我现在正在尝试一个非常强大的 git merge 操作 我遇到的一个问题是 我对分支中的某些代码进行了一些更改 但我的同事将该代码移动到了他分支中的新文件中 所以当我这样做的时候git merge my branch his branch
  • 使用 strptime() 解析日期/时间字符串时如何保留时区?

    我有一个来自 Blackberry IPD 备份的 CSV 转储文件 是使用 IPDDump 创建的 这里的日期 时间字符串看起来像这样 在哪里EST是澳大利亚时区 Tue Jun 22 07 46 22 EST 2010 我需要能够在 P
  • Arduino从SD卡读取最后一行

    我对 Arduino 业务还很陌生 如何从 SD 卡读取最后一行 通过以下代码片段 我可以读取第一行 n 之前的所有字符 现在我想添加一个 向后 声明 或其他内容 到目前为止我的代码 include
  • 寻找 Wii 兼容的 Javascript Flash mp3 播放器

    我正在寻找一款能够在 Wii 上基于 Opera 的浏览器中运行的 flash mp3 播放器 播放器需要启用 javascript 支持播放 停止等方法 mp3 曲目列表将使用与播放器相同的页面上的 ajax 动态构建 因此当曲目完成播放
  • Android:在 Android 设备选择器中,同一设备会出现多次

    我正在使用 Eclipse 为 Android 操作系统编程 我使用真实设备来测试我的应用程序 为了测试我的应用程序 我单击 运行 然后单击我想要运行的目标项目 然后弹出 Android 设备选择器 我可以在其中选择要运行该应用程序的设备或
  • 脚本标签中的文本属性 - 澄清?

    在阅读 Angular 的指令代码时 我看到this https github com angular angular js blob master src ng directive script js L43 var scriptDire