<template>: コンテンツテンプレート要素
HTML のコンテンツテンプレート (<template>
) 要素 は、すなわちページの読み込み時にすぐには描画されないものの、後で JavaScript を使用してインスタンスを生成できる HTML を保持するメカニズムです。
テンプレートは、文書内に格納されたコンテンツの断片として考えてください。ページの読み込み時にパーサーが <template>
要素の内容を処理している間、その内容の有効性のみが検証されます。しかし、要素の内容は描画されません。
コンテンツカテゴリ | メタデータコンテンツ, フローコンテンツ, 記述コンテンツ, スクリプト対応要素 |
---|---|
許可されている内容 | 制限なし |
タグの省略 | 不可。開始と終了タグの両方が必要。 |
許可されている親要素 | メタデータコンテンツ, 記述コンテンツ, スクリプト対応要素 を受け付けるすべての要素。また、 span 属性を持たない <colgroup> 要素の子になることもできます。 |
暗黙の ARIA ロール | 対応するロールなし |
許可されている ARIA ロール | 許可されている role なし |
DOM インターフェイス | HTMLTemplateElement |
属性
この要素には、グローバル属性のみがあります。
ただし、 HTMLTemplateElement
の content
プロパティは、読み取り専用の DocumentFragment
で、テンプレートが表現する DOM サブツリーを保持しています。なお、 content
の値を直接使用すると予想外の動作につながる可能性があります。下記の DocumentFragment の落とし穴の回避の節を参照してください。
例
まず、HTML 部分の例から始めましょう。
<table id="producttable">
<thead>
<tr>
<td>UPC_Code</td>
<td>Product_Name</td>
</tr>
</thead>
<tbody>
<!-- 必要に応じて既存のデータをここに含められます。 -->
</tbody>
</table>
<template id="productrow">
<tr>
<td class="record"></td>
<td></td>
</tr>
</template>
まず、JavaScript コードを使用して後からコンテンツを挿入するための table を作ります。次に、1 行分を表す HTML 断片の構造が書かれた template が続きます。
table が生成され、 template が定義されました。 JavaScript を使って、 template を基に構築される各行を table に挿入します。
// templete 要素の content 属性の有無を確認することで、
// ブラウザーが HTML template 要素に対応しているかテストします。
if ('content' in document.createElement('template')) {
// 既存の HTML tbody と template の行を使って
// table をインスタンス生成します。
var tbody = document.querySelector("tbody");
var template = document.querySelector('#productrow');
// 新しい行を複製して表に挿入します。
var clone = template.content.cloneNode(true);
var td = clone.querySelectorAll("td");
td[0].textContent = "1235646565";
td[1].textContent = "Stuff";
tbody.appendChild(clone);
// 新しい行を複製して表に挿入します。
var clone2 = template.content.cloneNode(true);
td = clone2.querySelectorAll("td");
td[0].textContent = "0384928528";
td[1].textContent = "Acme Kidney Beans 2";
tbody.appendChild(clone2);
} else {
// HTML template 要素に対応していないので
// 表に行を追加するほかの方法を探します。
}
結果として、 JavaScript を通して、新しい行が追加された HTML の表ができます。
DocumentFragment の落とし穴の回避
DocumentFragment
は様々なイベントのために有効なターゲットではないので、その中の要素を複製したり、参照したりすることが好ましいことがよくあります。
以下の HTML および JavaScript を考えてみてください。
HTML
<div id="container"></div>
<template id="template">
<div>Click me</div>
</template>
JavaScript
const container = document.getElementById("container");
const template = document.getElementById("template");
function clickHandler(event) {
alert("Clicked a div");
}
const firstClone = template.content.cloneNode(true);
firstClone.addEventListener("click", clickHandler);
container.appendChild(firstClone);
const secondClone = template.content.firstElementChild.cloneNode(true);
secondClone.addEventListener("click", clickHandler);
container.appendChild(secondClone);
結果
firstClone
は DocumentFragment のインスタンスなので、期待通りにコンテナー内に追加されますが、クリックしてもクリックイベントは発生しません。 secondClone
は HTMLDivElement
のインスタンスなので、クリックすると期待通りに動作します。
仕様書
仕様書 | 状態 | 備考 |
---|---|---|
HTML Living Standard template element の定義 |
現行の標準 | |
HTML5 template element の定義 |
勧告 | 初回定義 |
ブラウザーの互換性
BCD tables only load in the browser
関連情報
- ウェブコンポーネント:
<slot>
(および過去の<shadow>
) - テンプレートとスロットの利用