目录

🥮 template 模版元素

内建的 <template> 元素用来存储 HTML 模板。浏览器将 忽略它的内容,仅检查语法的有效性,但是可以在 JavaScript 中 访问和使用它来创建其他元素。理论上,可以在 HTML 的任何位置创建不可见元素来存储 HTML 模版。

# 创建模版元素

模版元素 <template> 的优势:

  • 内容可以是任何有效的 HTML。即使它通常需要特定的封闭标签。

    🌰 例子:

    <template>
      <tr>
        <td>Contents</td>
      </tr>
    </template>
    
    1
    2
    3
    4
    5

    通常如果在 <tr> 内放置类似 <div> 的元素,浏览器会检测到无效的 DOM 结构并对其进行 “修复”,然后用 <table> 封闭 <tr> ,那不是我们想要的。

    <template> 则会完全保留储存的内容。

    🌰 例子 / 尝试将脚本和样式放入模版元素中:

    <template>
      <style>
        p { font-weight: bold; }
      </style>
      <script>
        alert("Hello");
      </script>
    </template>
    
    1
    2
    3
    4
    5
    6
    7
    8

    浏览器认为 <template> 的内容 “不在文档中”:样式不会被应用,脚本也不会被执行, <video autoplay> 也不会运行,等。

    但是当将内容插入文档时,该内容将变为活动状态(应用样式,运行脚本等)。

# 插入模版

模板的 content 属性可看作是 DocumentFragment ( 一种特殊的 DOM 节点 🍥 JavaScript DOM 操作)。可以将其视为普通的 DOM 节点,除了它有一个特殊属性:将模版插入某个位置时,会被插入的是其子节点

🌰 例子:

<template id="tmpl">
  <script>
    alert("Hello");
  </script>
  <div class="message">Hello, world!</div>
</template>

<script>
	let elem = document.createElement('div')
  
  // 克隆模版元素以便重用
  elem.append(templ.content.cloneNode(true))

	// 将元素插入到文档中
  document.body.append(elem)
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

🌰 例子 / 插入模版到影子 DOM :

<template id="tmpl">
  <style> p { font-weight: bold; } </style>
  <p id="message"></p>
</template>

<div id="elem">Click me</div>

<script>
	elem.onclick = function() {
    elem.attachShadow({mode: 'open'});
    
    elem.shadowRoot.append(templ.content.cloneNode(true));
  
  	elem.shadowRoot.getElementById('message').innerHTML = "Hello from shadow DOM";
  }
</script>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

tmpl.content 作为 DocumentFragment 克隆和插入,它的子节点( <style><p> )将代为插入。他们会变成一个 shadow DOM :

<div id="elem">
  #shadow-root
    <style> p { font-weight: bold; } </style>
    <p id="message"></p>
</div>
1
2
3
4
5

# 总结

  • <template> 的内容可以是任何语法正确的 HTML。
  • <template> 内容被视为 “超出文档范围”,因此它不会产生任何影响。
  • 可以在 JavaScript 中访问 template.content ,将其克隆以在新组件中重复使用。

<template> 标签非常独特,因为:

  • 浏览器将检查其中的 HTML 语法(与在脚本中使用模板字符串不同)。
  • 但允许使用任何顶级 HTML 标签,即使没有适当包装元素的无意义的元素(例如 <tr> )。
  • 其内容是交互式的:插入其文档后,脚本会运行, <video autoplay> 会自动播放。

<template> 元素不具有任何迭代机制,数据绑定或变量替换的功能,但可以在其基础上实现这些功能。

📢 上次更新: 2022/09/02, 10:18:16