Установка document.body.outerHTML создает пустые головы. Зачем?
Сброс 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>
Все браузеры в этом согласны. Мне сказали, что это определено именно так, но я не смог выкопать авторитетную позицию стандартов по этому поводу, даже не упомянул в архивах обсуждений. Знаете ли вы какой-то фон из этого, или есть какая-то техническая причина, по которой так должно быть? Любая идея?
1 ответ
Интересный вопрос. К сожалению, объяснение скрыто в деталях алгоритма разбора фрагмента HTML, на который ссылаются из определения externalHTML в спецификации DOM Parsing.
Вам нужно очень внимательно следить за состояниями синтаксического анализатора, чтобы понять, почему, но по сути это работает так. При использовании externalHTML анализатор инициализируется так, как будто он только что проанализировал начальный тег родительского узла данного узла. Для document.body это html
элемент.
В алгоритме разбора HTML, когда html
разбирается начальный тег, следующая вещь, которую ожидает парсер head
элемент. Но поскольку в HTML начальный и конечный теги элемента head являются необязательными, если он не видит следующий начальный тег, он выводит один. Так что в случае document.body.outerHTML следующая вещь, которую видит анализатор, это body
начальный тег, и поэтому сначала создается пустой элемент head.
Наконец, после анализа фрагмента в DOM добавляется вся партия, включая выводимый элемент head.