2022年4月14日

テンプレート要素

組み込みの <template> 要素は、HTMLマークアップテンプレートのストレージとして機能します。ブラウザはコンテンツを無視し、構文の有効性のみをチェックしますが、JavaScriptでアクセスして使用し、他の要素を作成できます。

理論的には、HTMLマークアップの保存目的で、HTMLのどこかに非表示の要素を作成できます。<template>の特別な点は何でしょうか?

まず、そのコンテンツは、通常は適切な囲みタグを必要とする場合でも、任意の有効なHTMLにすることができます。

たとえば、テーブル行<tr>をそこに配置できます。

<template>
  <tr>
    <td>Contents</td>
  </tr>
</template>

通常、たとえば、<div>の中に<tr>を配置しようとすると、ブラウザは無効なDOM構造を検出し、「修正」して、周囲に<table>を追加します。それは私たちが望むものではありません。一方、<template>はそこに配置したものを正確に保持します。

スタイルとスクリプトを<template>に入れることもできます。

<template>
  <style>
    p { font-weight: bold; }
  </style>
  <script>
    alert("Hello");
  </script>
</template>

ブラウザは<template>コンテンツを「ドキュメントの外」と見なします。スタイルは適用されず、スクリプトは実行されず、<video autoplay>は実行されませんなど。

コンテンツがライブになる(スタイルが適用され、スクリプトが実行されるなど)のは、ドキュメントに挿入したときです。

テンプレートの挿入

テンプレートのコンテンツは、DocumentFragment – 特殊なタイプのDOMノードとして、そのcontentプロパティで利用できます。

特別なプロパティを1つ除いて、他の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>

前の章のShadow DOMの例を<template>を使用して書き直してみましょう。

<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>)が代わりに挿入されます。

それらがシャドウ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>要素には、反復メカニズム、データバインディング、変数置換は含まれていませんが、それらの上に実装できます。

チュートリアルマップ

コメント

コメントする前にこれを読んでください…
  • 改善するための提案がある場合は、コメントする代わりにGitHub issueを提出するか、プルリクエストをしてください。
  • 記事の内容で理解できないことがある場合は、詳しく説明してください。
  • コードを数語挿入するには、<code>タグを使用します。複数行の場合は、<pre>タグで囲み、10行を超える場合は、サンドボックス(plnkrjsbincodepen…)を使用してください。