<template> 中的 outerHTML 行为

outerHTML behavior in a <template>

鉴于此 <template>

<template id="my-template">
    <h1 id="h">Hello!</h1>
</template> 

和 JS:

var t = document.querySelector("#my-template");
var h = t.content.querySelector("h1");
h.outerHTML = "<h3>AAAAAAAAAAAAAA</h3>";

有趣的是,它在 FireFox 和 Edge 中有效,但在 Chrome 中 outerHTML 需要父元素,否则它会在控制台中抛出错误 (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> 

https://jsfiddle.net/q5fmn186/11/

我的问题是,Chrome 行为是否正确?设置 outerHTML 不应该在 <template> 中对直接子项起作用吗?为什么其他网络浏览器不将其视为错误?

其他网络浏览器不会将其视为错误,因为它们遵循 DOM Parsing and Serialization W3C Candidate Recommendation(目前还不是标准):

On setting [outerHTML], the following steps must be run:

  1. Let parent be the context object's parent.
  2. 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.
  3. If parent is a Document, throw a DOMException with name "NoModificationAllowedError" exception.
  4. 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.
  5. Let fragment be the result of invoking the fragment parsing algorithm with the new value as markup, and parent as the context element.
  6. Replace the context object with fragment within the context object's parent.

<template>contentDocumentFragment 类型(第 4 步),但(在这种情况下)被视为Document(第 3 步)由 Chrome 和 Safari。