Setting document.body.outerHTML creates empty heads. Why?
Asked Answered
P

1

10

Resetting outerHTML property of document.body has a strange side effect: it adds extra empty <head></head> into the DOM, just before 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>

All browsers seem to be consistent in this. I've been told it is specified to be this way, but was not able to dig up authoritative standards stance about this, not even any mention in discussion archives. Do you know some background of this, or is there some technical reason it has to be this way? Any idea?

Passable answered 19/10, 2018 at 8:13 Comment(2)
because contents of body is replaceable but body itself isn't? anyway it looks like a bug.Chibouk
@ChaseChoi but the bug report was closed as invalid citing it behaving according to spec. And it seems that it's universal across browsers.Pothook
O
7

Interesting question. Unfortunately the explanation is buried in the details of the HTML fragment parsing algorithm which is referenced from the definition of outerHTML in the DOM Parsing spec.

You'll need to follow the parser states through very carefully to see why, but in essence it works like this. With outerHTML, the parser is initialised as if it has just parsed the start tag of the given node's parent. For document.body, that's the html element.

In the HTML parsing algorithm, when an html start tag is parsed, the next thing the parser expects is a head element. But because, in HTML, the start and end tags of the head element are optional, if it doesn't see a head start tag next, it infers one. So in the case of document.body.outerHTML, the next thing the parser sees is the body start tag, and so creates an empty head element first.

Finally, once the fragment is parsed, the whole lot, including the inferred head element is added to the DOM.

Organist answered 20/10, 2018 at 8:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.