16

我正在创建一个实时 HTML 编辑器,它在渲染 DOM 后加载,并通过循环遍历所有节点来构建源代码。我注意到,当我尝试读取包含 HTML 实体的文本节点的 nodeValue 时,我总是得到该实体的呈现 unicode 值。

如何读取呈现的文本节点并保留 HTML 实体代码?(使用香草JS)

例子:

<div id="test">copyright &copy;</div>
<script>
var test = document.getElementById('test');
console.log(test.childNodes[0].nodeValue);
// expected: copyright &copy;
// actual: copyright ©
</script>
4

1 回答 1

8

不幸的是你不能。Text接口继承自CharacterData 两个接口都只提供DOMStrings作为返回值,其中包含 Unicode 字符。

此外,HTML5 解析算法基本上完全删除了实体。这在8.2.4 Tokenization的几个部分中定义。

  • 8.2.4.1 数据状态:描述了一个&符号将解析器放入数据状态中的字符引用
  • 8.2.4.2 数据状态中的字符引用描述了应该使用与符号后面的令牌。如果一切正常,它将返回 Unicode 字符标记,而不是实体!
  • 8.2.4.69 标记字符引用描述了一个人如何解释&...;(基本上做一些事情,如果一切正常,在表格中查找)。

因此,当您的解析器完成时,实体已经消失并被 Unicode 符号取代。这并不奇怪,因为如果需要,您也可以将符号 © 直接放入 HTML 代码中。

但是,您仍然可以撤消该转换:您需要获取table的副本,并检查文档中的任何字符是否包含条目:

var entityTable = {
  169: "&copy;"
}

function reEntity(character){
  var index = character.charCodeAt(0), name;

  if( index < 127) // ignore ASCII symbols
    return character;

  if( entityTable[index] ) {
    name = entityTable[index];
  } else {
    name = "#"+index;
  }
  return "&"+name+";"
}

这是一项相当繁琐的任务,但由于解析器的行为,您可能必须这样做。(不要忘记检查是否有人已经这样做了)。

于 2013-07-11T01:17:55.360 回答