给定此<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>
直接子女身上起作用吗?为什么其他网络浏览器不将其视为错误?
其他 Web 浏览器不会将其视为错误,因为它们遵循 DOM 解析和序列化 W3C 候选建议(还不是标准):
在设置 [outerHTML] 时,必须运行以下步骤:
- 让父对象成为上下文对象的父对象。
- 如果父级为 null,请终止这些步骤。即使运行了其余步骤,也无法获取对创建的节点的引用。
- 如果父级是文档,则抛出名为"NoModificationAllowedError"的 DOMException 异常。
如果父级是- 文档片段,则让父级是一个新的元素,其 body 作为其本地名称,HTML 命名空间作为其命名空间,上下文对象的节点文档作为其节点文档。
- 让片段是调用片段解析算法的结果,新值作为标记,父值作为上下文元素。
将上下文对象- 替换为上下文对象的父对象中的片段。
<template>
的content
是DocumentFragment类型(步骤4),但在这种情况下,Chrome和Safari将其视为文档(步骤3)。