【问题标题】:Difference in HTML Entity length in JavaScriptJavaScript中HTML实体长度的差异
【发布时间】:2014-11-01 00:36:47
【问题描述】:

为什么实体  的长度为6,而实体↓ 的长度为1?这是在规范中的某个地方吗? (在 Firefox、Chrome 和 Safari 中测试。)

JSFiddle

【问题讨论】:

  • 可能是SGML中规定的,我看看
  • 如果我不得不猜测这是一个故意的错误,以保持向后兼容性fileformat.info/info/unicode/char/a0/index.htm 嗯 - 请注意.textContent 在任何一种情况下都会返回 1。
  • 有趣...是的,你是对的,它适用于 textContent (JSFiddle)

标签: html unicode innerhtml html-entities string-length


【解决方案1】:

我同意这是非常奇怪的行为,但至少它是指定的。

HTML fragment serialization algorithm 声明:

转义字符串(出于上述算法的目的)包括将任何出现的“&”字符替换为字符串“&”,任何出现的“" 字符由字符串 ">",任何出现的 U+00A0 NO-BREAK SPACE 字符由字符串 " ",并且,如果在属性模式下调用算法,字符串 """ 出现的任何 """ 字符。

我强调。如果我不得不猜测这是为了在执行此操作的旧浏览器中支持向后兼容性,并在反序列化和序列化字符串时获得一致的行为。如果浏览器将<div>  </div> 的DOM 树结果序列化为<div> </div>,再次将其反序列化为DOM 树将产生一个空格*。这几乎是浏览器实现一致行为的唯一方法。

另一方面,替换为 ↓ 是完全安全且有意义的。

如果您真的对使用 .textContent 存储在文本中的字符串的长度感兴趣,您会得到您感兴趣的结果。

* 好吧,不是真的,因为它仍然是   U+00A0 - 但我能理解为什么人们认为它在早期的 DOM 时代可能会令人困惑

【讨论】:

  • 感谢您查找此内容。但是我不明白你加粗的部分是如何解释这种行为的。我还应该补充一点,> 的行为方式与   相同。
  • @AmadeusDrZaius 在 DOM 规范中有 显式处理 - 它以及 &>"&lt 是 DOM 规范中的显式特殊情况。在我看来,至少对于  而言,这不会让人们混淆与正常空间(U+0020)的区别,但这确实是一个奇怪的案例。
  • 对不起,我一开始看错了引用的部分。所以你说的是浏览器首先转换所有实体......然后将这些特定字符转换回它们的实体形式?那么我唯一的问题是为什么浏览器不显示 ?我想我需要看到这一切的内部表示才有意义。
  • 是的,一个不间断的空格仍然是一个空格 - " " here 的所有代码。由于我只能估计向后兼容性的原因,浏览器会对其进行特殊处理。
【解决方案2】:

考虑以下 HTML sn-p:

<div>
  <p>foo &amp; bar &#x1D306; baz</p>
</div>

让我们look up innerHTML in the HTML Living Standard 看看当我们在上述 HTML 文档的上下文中运行 div.innerHTML 时会发生什么。啊,它遵从the DOM Parsing spec,上面写着:

在获取时,如果上下文对象的节点文档是 HTML 文档,则该属性必须返回对上下文对象运行 HTML 片段序列化算法的结果; […]

HTML 片段序列化算法是defined in the HTML Living Standard。按照考虑到div.innerHTML 示例的算法,很明显它第一次将下降到步骤3.2 下的“如果当前节点Element”分支。这会将&lt;p&gt; 添加到输出中。

然后它在文本节点内再次调用算法。这次我们结束了“if current node is a Text node”分支。它说:

[…] 否则,追加当前节点data IDL 属性的值,转义如下所述。

data IDL 属性包含元素的文本内容。转义指令为defined as follows:

转义字符串(出于上述算法的目的)包括运行以下步骤:

  1. 将任何出现的&amp;amp; 字符替换为字符串&amp;amp;

  2. 将所有出现的 U+00A0 NO-BREAK SPACE 字符替换为字符串 &amp;nbsp;

  3. 如果算法是在属性模式下调用的,请将所有出现的" 字符替换为字符串&amp;quot;

  4. 如果没有在属性模式下调用算法,则将所有出现的&amp;lt; 字符替换为字符串&amp;lt;,并将任何出现的&amp;gt; 字符替换为字符串&amp;gt;

.innerHTML 的结果中,只有上述符号被转义为 HTML 实体 - 其他 Unicode 符号仅以其原始形式显示,无论它们在 HTML 源代码中如何表示。

正因为如此,HTML源代码中的"&amp;darr;"在通过innerHTML读回时会变成"↓"。但是例如"&amp;amp;""&amp;#x26;"变成"&amp;amp;""&amp;nbsp;"&amp;#xA0;变成"&amp;nbsp;"

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多