Given this <template>
:
<template id="my-template">
<h1 id="h">Hello!</h1>
</template>
And JS:
var t = document.querySelector("#my-template");
var h = t.content.querySelector("h1");
h.outerHTML = "<h3>AAAAAAAAAAAAAA</h3>";
It's interesting that it works in FireFox and Edge but in Chrome outerHTML
requires a parent element, otherwise it throws error in console (https://chromium.googlesource.com/chromium/blink/+/master/Source/core/dom/Element.cpp#2528):
<template id="my-template">
<div>
<h1 id="h">Hello!</h1>
</div>
</template>
See https://jsfiddle.net/q5fmn186/11/
My question is, is Chrome behavior the correct one? Should setting outerHTML
not work in <template>
on direct children? Why aren't the other web-browser treat it like an error?
The other web browsers won't treat it like an error because they are following the DOM Parsing and Serialization W3C Candidate Recommendation (which is not a standard yet):
On setting [outerHTML], the following steps must be run:
- Let parent be the context object's parent.
- If parent is null, terminate these steps. There would be no way to obtain a reference to the nodes created even if the remaining steps were run.
- If parent is a Document, throw a DOMException with name "NoModificationAllowedError" exception.
- If parent is a DocumentFragment, let parent be a new Element with body as its local name, the HTML namespace as its namespace, and the context object's node document as its node document.
- Let fragment be the result of invoking the fragment parsing algorithm with the new value as markup, and parent as the context element.
- Replace the context object with fragment within the context object's parent.
The <template>
's content
is of type DocumentFragment (step 4) but it is treated (in this situation) as a Document (step 3) by Chrome and Safari.