浏览器如何处理 <template> 标签与 <div> 标签
How does a browser handle a <template> tag VS a <div> tag
我一直在阅读有关 <template>
标签的文档,我似乎无法理解它与简单地使用 <div>
即 display: none;
[= 有何不同20=]
文档:template tag
<template>
示例
<template id="productrow">
<tr>
<td class="record"></td>
<td></td>
</tr>
</template>
VS
<div>
例子
<div id="productrow" style="display: none">
<tr>
<td class="record"></td>
<td></td>
</tr>
</div>
- 在低层次上,浏览器如何以不同方式处理这两个示例?
- 某些 JS 方法或 HTML 属性是否不同或不可用?
PS:我知道浏览器兼容性差异
考虑:
<template>
<style>
body: { background-color: black; }
</style>
<script>
alert('hello');
</script>
<audio src="alert.wav" autoplay></audio>
</template>
并且:
<div style="display: none;">
<style>
body: { background-color: black; }
</style>
<script>
alert('hello');
</script>
<audio src="alert.wav" autoplay></audio>
</div>
当浏览器呈现它们时,它们的行为是否相同? (剧透:没有。)
不过,要解决您的具体问题:
- On a low level, how does the browser handle these 2 examples differently?
首先,<template>
中的 HTML 不会成为 <template>
的子元素 DOM。它成为 "inert" DocumentFragment 的子节点(间接地;这是一种简化),它们作为节点存在但不 "do" 任何东西,如上例所示。
除了 "inert," 之外,模板内容没有 "conformance requirements." 您上面的 <tr>
示例很好。看看这里发生了什么:
const template = document.querySelector('template');
const div = document.querySelector('div');
console.log('template.innerHTML is', template.innerHTML);
console.log('div.innerHTML is', div.innerHTML);
<template>
<tr>
<td class="record"></td>
<td></td>
</tr>
</template>
<div style="display: none">
<tr>
<td class="record"></td>
<td></td>
</tr>
</div>
在普通文档中,<tr>
不能是 <div>
的子元素,因此浏览器会将其删除。在 <template>
中,该要求不存在。你会发现与 <div style="{{myStyle}}">
相同。在文档中,浏览器会丢弃 style
属性,因为它的值无效;在 <template>
中它不会。这就是 <template>
对模板有用的原因。
如果您想了解更多关于 <template>
是如何渲染的,我建议您阅读 section about it in the HTML spec。读起来并不容易,部分内容可能难以理解,但你会学到很多东西。
- Are certain JS methods or HTML attributes different or not available?
<template>
元素具有 content
属性,指向上面讨论的 DocumentFragment。
JS 中的任何选择器都找不到 <template>
内的元素,因此您不会意外找到它们,要提取它们,您必须使用 content
属性 的 HTMLTemplateElement 使用类似的东西:
var clone = document.importNode(templateElement.content, true);
此外,每个 <style>
、<audio>/<video>/...
或 <script>
都会在页面加载时被解析,但 运行 直到您将其克隆到主 [=21] =].
我找到了一篇详细解释所有差异的文章:
https://www.html5rocks.com/en/tutorials/webcomponents/template/
我现在意识到 <div>
示例实际上是旧版浏览器中使用的一种 polyfill,必须进行严重的黑客攻击才能使其按预期工作。
感谢大家的帮助。
我一直在阅读有关 <template>
标签的文档,我似乎无法理解它与简单地使用 <div>
即 display: none;
[= 有何不同20=]
文档:template tag
<template>
示例
<template id="productrow">
<tr>
<td class="record"></td>
<td></td>
</tr>
</template>
VS
<div>
例子
<div id="productrow" style="display: none">
<tr>
<td class="record"></td>
<td></td>
</tr>
</div>
- 在低层次上,浏览器如何以不同方式处理这两个示例?
- 某些 JS 方法或 HTML 属性是否不同或不可用?
PS:我知道浏览器兼容性差异
考虑:
<template>
<style>
body: { background-color: black; }
</style>
<script>
alert('hello');
</script>
<audio src="alert.wav" autoplay></audio>
</template>
并且:
<div style="display: none;">
<style>
body: { background-color: black; }
</style>
<script>
alert('hello');
</script>
<audio src="alert.wav" autoplay></audio>
</div>
当浏览器呈现它们时,它们的行为是否相同? (剧透:没有。)
不过,要解决您的具体问题:
- On a low level, how does the browser handle these 2 examples differently?
首先,<template>
中的 HTML 不会成为 <template>
的子元素 DOM。它成为 "inert" DocumentFragment 的子节点(间接地;这是一种简化),它们作为节点存在但不 "do" 任何东西,如上例所示。
除了 "inert," 之外,模板内容没有 "conformance requirements." 您上面的 <tr>
示例很好。看看这里发生了什么:
const template = document.querySelector('template');
const div = document.querySelector('div');
console.log('template.innerHTML is', template.innerHTML);
console.log('div.innerHTML is', div.innerHTML);
<template>
<tr>
<td class="record"></td>
<td></td>
</tr>
</template>
<div style="display: none">
<tr>
<td class="record"></td>
<td></td>
</tr>
</div>
在普通文档中,<tr>
不能是 <div>
的子元素,因此浏览器会将其删除。在 <template>
中,该要求不存在。你会发现与 <div style="{{myStyle}}">
相同。在文档中,浏览器会丢弃 style
属性,因为它的值无效;在 <template>
中它不会。这就是 <template>
对模板有用的原因。
如果您想了解更多关于 <template>
是如何渲染的,我建议您阅读 section about it in the HTML spec。读起来并不容易,部分内容可能难以理解,但你会学到很多东西。
- Are certain JS methods or HTML attributes different or not available?
<template>
元素具有 content
属性,指向上面讨论的 DocumentFragment。
JS 中的任何选择器都找不到 <template>
内的元素,因此您不会意外找到它们,要提取它们,您必须使用 content
属性 的 HTMLTemplateElement 使用类似的东西:
var clone = document.importNode(templateElement.content, true);
此外,每个 <style>
、<audio>/<video>/...
或 <script>
都会在页面加载时被解析,但 运行 直到您将其克隆到主 [=21] =].
我找到了一篇详细解释所有差异的文章: https://www.html5rocks.com/en/tutorials/webcomponents/template/
我现在意识到 <div>
示例实际上是旧版浏览器中使用的一种 polyfill,必须进行严重的黑客攻击才能使其按预期工作。
感谢大家的帮助。