8

重置outerHTML属性document.body有一个奇怪的副作用:它<head></head>在 DOM 中添加了额外的空,就在之前body

head { display: inline; counter-increment: h; border: 1px solid; }
head:last-of-type::after { content: 'Head elements count: ' counter(h); }
[onclick]::after { content: attr(onclick); }
<button onclick="document.body.outerHTML=document.body.outerHTML"></button>

所有浏览器似乎都是一致的。我被告知它被指定为这种方式,但无法挖掘权威标准的立场,甚至在讨论档案中也没有提及。你知道这方面的一些背景,还是有一些技术原因必须这样?任何的想法?

4

1 回答 1

4

有趣的问题。不幸的是,解释隐藏在HTML 片段解析算法的细节中,该算法引用自DOM Parsing 规范中的outerHTML定义。

您需要非常仔细地跟踪解析器状态以了解原因,但本质上它是这样工作的。使用outerHTML,解析器被初始化,就好像它刚刚解析了给定节点的父节点的开始标记。对于 document.body,这就是html元素。

在 HTML 解析算法中,当一个html开始标签被解析时,解析器接下来需要的是一个head元素。但是因为在 HTML 中,head 元素的开始和结束标签是可选的,如果接下来没有看到 head 开始标签,它会推断出一个。所以在 document.body.outerHTML 的情况下,解析器接下来看到的是body开始标签,因此首先创建了一个空的 head 元素。

最后,一旦片段被解析,整个片段,包括推断的 head 元素都被添加到 DOM 中。

于 2018-10-20T08:39:22.790 回答