text nodeValue包含HTML实体

时间:2013-07-10 22:40:03

标签: javascript

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

如何读取渲染文本节点,并保留HTML实体代码? (使用vanilla 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>

1 个答案:

答案 0 :(得分:6)

不幸的是你做不到。 Text 接口继承自 CharacterData ,两个接口仅提供 DOMStrings 作为返回值,包含Unicode字符。

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

  • 8.2.4.1数据状态:描述&符号将解析器放入数据状态的字符引用
  • 8.2.4.2数据状态中的字符引用描述应使用&符号后跟的符号。如果一切正常,它将返回Unicode字符标记,而不是实体!
  • 8.2.4.69标记字符引用描述了如何解释&...;(基本上做了一些事情,如果一切正常,look it up in the table)。

因此,当您的解析器完成时,实体已经消失,并且已被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+";"
}

这是一项非常麻烦的任务,但由于解析器的行为,您可能必须这样做。 (别忘了检查某人是否已经这样做了。)