昨天我卷入了一场关于 DOM 实现怪癖的讨论,引发了一个关于 Text.splitText 和 Element.normalise 行为以及它们应该如何表现的有趣问题。

DOM 1 级核心, Text.splitText 定义为...

将此 Text 节点按指定偏移量分成两个 Text 节点,将两者作为同级节点保留在树中。然后,该节点仅包含直到偏移点的所有内容。新的 Text 节点作为该节点的下一个兄弟节点插入,包含偏移点处及其之后的所有内容。

标准化是...

将此元素下面的子树的整个深度中的所有文本节点放入“正常”形式,其中仅标记(例如,标签、注释、处理指令、CDATA 部分和实体引用)分隔文本节点,即,有没有相邻的文本节点。这可用于确保文档的 DOM 视图与保存和重新加载时相同,并且在要使用依赖于特定文档树结构的操作(例如 XPointer 查找)时非常有用。

因此,如果我获取一个包含“Hello World”的文本节点(在 textNode 中引用),然后执行

textNode.splitText(3)

textNode 现在具有内容“Hello”,以及一个包含“World”的新同级节点

如果我那么

textNode.parent.normalize()

什么是文本节点?该规范没有明确说明 textNode 仍然必须是其先前父节点的子节点,只是更新以包含所有相邻的文本节点(然后将其删除)。删除所有相邻的文本节点,然后通过值的串联重新创建一个新节点,使 textNode 指向不再属于树的一部分,这似乎是一种一致的行为。或者,我们可以以与 splitText 相同的方式更新 textNode,因此它保留其树位置,并获取新值。

行为的选择确实非常不同,我找不到关于哪个是正确的说明,或者这是否只是规范中的一个疏忽(似乎在第 2 级或第 3 级中没有得到澄清)。有哪位 DOM/XML 专家可以解释一下吗?

有帮助吗?

解决方案

我早期是 DOM 工作组的成员;我确信我们 意思是 让 textNode 包含新加入的值,但如果我们没有 它在规范中,有可能 一些 执行 可能 创建一个新节点而不是重用 textNode,尽管这需要实现者做更多的工作。

如有疑问,请进行防御性编程。

其他提示

虽然这看起来是一个合理的假设,但我同意规范中没有明确说明这一点。我能补充的是,我阅读它的方式,其中之一 textNode 或者它是新的兄弟姐妹(即返回值来自 splitText) 将包含新的连接值 - 该语句指定所有节点 在子树中 被置于规范形式,而不是子树被规范化为新的结构。我想唯一安全的事情是在标准化之前保留对父级的引用。

我认为所有的赌注都在这里了;我当然不会依赖于任何特定的行为。唯一安全的做法是再次从其父节点获取该节点。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top