內建的 <template>
元素用於儲存 HTML 標記範本。瀏覽器會忽略其內容,只檢查語法是否正確,但我們可以在 JavaScript 中存取並使用它來建立其他元素。
理論上,我們可以在 HTML 中的某個地方建立任何不可見的元素,用於儲存 HTML 標記。<template>
有什麼特別之處?
首先,它的內容可以是任何有效的 HTML,即使它通常需要一個適當的封閉標籤。
例如,我們可以放一個表格列 <tr>
<template>
<tr>
<td>Contents</td>
</tr>
</template>
通常,如果我們嘗試將 <tr>
放在例如 <div>
內部,瀏覽器會偵測到無效的 DOM 結構並「修復」它,在周圍加上 <table>
。這不是我們想要的。另一方面,<template>
會保留我們放在那裡的內容。
我們也可以將樣式和腳本放入 <template>
<template>
<style>
p { font-weight: bold; }
</style>
<script>
alert("Hello");
</script>
</template>
瀏覽器將 <template>
內容視為「超出文件」:樣式不會套用,腳本不會執行,<video autoplay>
也不會執行,等等。
當我們將內容插入文件時,內容就會變成動態(套用樣式、執行腳本等)。
插入範本
範本內容可以在其 content
屬性中作為 DocumentFragment 取得,這是一種特殊的 DOM 節點。
我們可以將它視為任何其他 DOM 節點,除了有一個特殊屬性:當我們將它插入某處時,會插入它的子節點。
例如
<template id="tmpl">
<script>
alert("Hello");
</script>
<div class="message">Hello, world!</div>
</template>
<script>
let elem = document.createElement('div');
// Clone the template content to reuse it multiple times
elem.append(tmpl.content.cloneNode(true));
document.body.append(elem);
// Now the script from <template> runs
</script>
讓我們使用 <template>
重寫前一章的 Shadow 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(tmpl.content.cloneNode(true)); // (*)
elem.shadowRoot.getElementById('message').innerHTML = "Hello from the shadows!";
};
</script>
在 (*)
行中,當我們複製並插入 tmpl.content
時,由於它是 DocumentFragment
,會插入它的子節點(<style>
、<p>
)。
它們組成了 Shadow DOM
<div id="elem">
#shadow-root
<style> p { font-weight: bold; } </style>
<p id="message"></p>
</div>
摘要
總之
<template>
內容可以是任何語法正確的 HTML。<template>
內容被視為「超出文件」,因此它不會影響任何東西。- 我們可以從 JavaScript 存取
template.content
,複製它以在新的元件中重複使用。
<template>
標籤非常獨特,因為
- 瀏覽器會檢查其內部的 HTML 語法(與在腳本中使用範本字串相反)。
- …但仍然允許使用任何頂層 HTML 標籤,即使那些沒有適當包裝器(例如
<tr>
)也沒有意義。 - 當插入文件時,內容會變成互動式:執行腳本、播放
<video autoplay>
等。
<template>
元素沒有任何反覆運算機制、資料繫結或變數替換,但我們可以在它的基礎上實作這些功能。
留言
<code>
標籤,若要插入多行程式碼,請將其包覆在<pre>
標籤中,若要插入超過 10 行程式碼,請使用沙盒 (plnkr、jsbin、codepen…)