设置 document.body.outerHTML 会创建空头。为什么?

Setting document.body.outerHTML creates empty heads. Why?

重置 document.bodyouterHTML 属性 有一个奇怪的副作用:它会在 [=16] 之前向 DOM 添加额外的空 <head></head> =]:

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>

所有浏览器似乎在这一点上都是一致的。我已经 been told 它被指定为这种方式,但无法挖掘出关于此的权威标准立场,甚至在讨论档案中也没有提及。您知道这方面的一些背景吗,或者是否有一些技术原因必须这样?有什么想法吗?

有趣的问题。不幸的是,解释隐藏在 DOM 解析规范 HTML fragment parsing algorithm which is referenced from the definition of outerHTML 的细节中。

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

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

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