【问题标题】:Why doesn't the DOM prevent appending a <div> into a <p> element?为什么 DOM 不阻止将 <div> 附加到 <p> 元素中?
【发布时间】:2017-07-28 21:31:32
【问题描述】:

这是一个关于 HTML5 解析器和 DOM API 之间关系的更一般问题的示例。 HTML 中不允许某些显然与 DOM API 无关的内容 - 因此您可以通过 DOM 创建“不允许的”HTML 情况。

例如根据 HTML5 规范,the p element 的内容模型只有“短语内容”。现在"content model" 是“关于必须包含哪些内容作为元素的子元素和后代元素的规范描述”。 "phrasing content" 基本上是文本和“段落内”标记,如链接和跨度,而不是 div 元素。

确实,如果我制作 HTML 文档或导致 HTML sn-p 像这样解析,则 div 会被强制“取消嵌套”:

var containerEl = document.createElement('body');
containerEl.innerHTML = "<p><div></div></p>";
console.log(containerEl.innerHTML); // -> "<p></p><div></div><p></p>"

似乎在解析过程中,“原始”段落被分成两部分,中间是 div。

但是,这段代码让我可以毫无问题地将div 插入p

 let pEl = document.createElement('p'),
     divEl = document.createElement('div');
 pEl.appendChild(divEl);
 console.log(pEl.outerHTML);     // -> "<p><div></div></p>"

现在 DOM Level 3 规范说,如果插入了错误的“类型”节点,.appendChild method 可以引发 DOMException

HIERARCHY_REQUEST_ERR:如果此节点的类型不允许 newChild 节点类型的子节点,则引发

我怀疑在这种情况下“类型”可能更多地指代,例如您不能将 Element 节点附加为 Text 节点的子节点。

标准中是否有任何内容澄清了这里的行为,承认了差异?解析 HTML 时不允许通过 JavaScript 创建 DOM 层次结构会产生什么后果?

【问题讨论】:

标签: html dom specifications


【解决方案1】:

标准中是否有任何内容澄清了这里的行为,承认了差异?

是的,html5 standard 提到了 DOM != HTML != XHTML

1.8 HTML 与 XML 语法

DOM、HTML 语法和 XML 语法不能都代表 相同的内容。例如,命名空间不能使用 HTML 语法,但它们在 DOM 和 XML 语法中受支持。 类似地,可以表示使用 noscript 功能的文档 使用 HTML 语法,但不能用 DOM 或在 XML 语法。包含字符串“-->”的注释只能是 在 DOM 中表示,而不是在 HTML 和 XML 语法中。


在解析 HTML 时不允许通过 JavaScript 创建 DOM 层次结构会产生什么后果?

取决于你在做什么。它可能导致跨浏览器的行为不一致。它可能会导致令人惊讶的造型。或者它可能导致内容不被渲染。例如。将&lt;p&gt; 插入&lt;select&gt; 不会使其呈现。

fragment parsing algorithms(例如insertAdjacentHTMLinnerTHML)相比,直接节点操作API(例如appendChild)将显示不同的行为,因为后者本质上是在创建时通过文档解析器和perform adjustments运行文本DOM 树基于文本中的HTML-specific rules,而节点操作 API 更通用,不知道此类调整。

【讨论】:

    猜你喜欢
    • 2014-03-10
    • 2016-07-24
    • 2015-10-02
    • 1970-01-01
    • 2017-12-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-24
    相关资源
    最近更新 更多