浏览器如何处理标签<template>与<div>标签


标签。

我一直在阅读有关<template>标签的文档,我似乎无法理解它与简单地使用<div>有何不同display: none;

文档:模板标签

<template>示例

<template id="productrow">
<tr>
<td class="record"></td>
<td></td>
</tr>
</template>

<div>示例

<div id="productrow" style="display: none">
<tr>
<td class="record"></td>
<td></td>
</tr>
</div>
  1. 在低层次上,浏览器如何处理这两个示例?
  2. 某些 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>

当浏览器呈现它们时,它们的行为是否相同?(剧透:没有。

但是,要解决您的具体问题,请执行以下操作:

  1. 在低层次上,浏览器如何处理这两个示例?

首先,<template>内的 HTML 不会成为作为<template>子级的 DOM 元素。它成为"惰性"DocumentFragment(间接;这是一种简化)的子级,它们作为节点存在,但不"执行"任何操作,如上例所示。

除了"惰性"之外,模板内容没有"一致性要求"。你上面<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>是如何呈现的,我建议阅读HTML规范中关于它的部分。阅读起来并不容易,部分内容可能难以理解,但你可以学到很多东西。

  1. 某些JS方法或HTML属性是否不同或不可用?

<template>元素具有content属性,该属性指向上面讨论的 DocumentFragment。

<template>中的任何选择器都找不到 GENES 中的元素,因此您不会意外找到它们,并且要提取它们,您必须使用 HTMLTemplateElement 的content属性,如下所示:

var clone = document.importNode(templateElement.content, true);

此外,每个<style><audio>/<video>/...<script>都会在页面加载时解析,但在您将其克隆到主 DOM 之前不会运行。

我找到了一篇文章,详细解释了所有差异: https://www.html5rocks.com/en/tutorials/webcomponents/template/

我现在意识到<div>示例实际上是旧浏览器中使用的填充码,必须对其进行严重黑客攻击才能使其按预期工作。

感谢大家的帮助。

最新更新