Web Components: template と slot を使ってみる

1. このページの目的

Web Components の template と slot を使ってみる。

template と slot の使い方 - Web Components | MDN に書いている例を、本ページで試す。

2. 基礎知識

(1) <template>

HTML テンプレート: <template><slot> 要素によって、レンダリングされたページ内に表示されないマークアップのテンプレートを書くことができます。カスタム要素の構造体の基礎として、それらを何度も再利用できます。

(引用元:Web Components | MDN

Shadow DOM と合わせて使うと有用性を増す。

(2) <slot>

(1種類のカスタムタグを複数回表示したい) && (一部だけ違う文字列を表示したい) 場合に使う。

カスタムタグ側で slot 属性を指定したHTMLタグを、テンプレート側の slot タグに置き換えることができる。

カスタムタグ側

<span slot="element-name">slot</span>

テンプレート側

<slot name="element-name">NEED NAME</slot>

3. デモ

以下の白いエリア内では、<element-details> というカスタムタグを作成して表示しています。

slot A placeholder inside a web component that users can fill with their own markup, with the effect of composing different DOM trees together.
name
The name of the slot.
template A mechanism for holding client- side content that is not to be rendered when a page is loaded but may subsequently be instantiated during runtime using JavaScript.

どのように要素が追加されているか Chrome DevTools で見てみる。

コードは、本ページのソースを表示すれば見られる。

4. コード

index.html 内のテンプレート部分

<template id="element-details-template">
  <style>
  details {font-family: "Open Sans Light",Helvetica,Arial}
  .name {font-weight: bold; color: #217ac0; font-size: 120%}
  h4 { margin: 10px 0 -8px 0; }
  h4 span { background: #217ac0; padding: 2px 6px 2px 6px }
  h4 span { border: 1px solid #cee9f9; border-radius: 4px }
  h4 span { color: white }
  .attributes { margin-left: 22px; font-size: 90% }
  .attributes p { margin-left: 16px; font-style: italic }
  </style>
  <details>
    <summary>
      <span>
        <code class="name">&lt;<slot name="element-name">NEED NAME</slot>&gt;</code>
        <i class="desc"><slot name="description">NEED DESCRIPTION</slot></i>
      </span>
    </summary>
    <div class="attributes">
      <h4><span>Attributes</span></h4>
      <slot name="attributes"><p>None</p></slot>
    </div>
  </details>
  <hr>
</template>

index.html 内のカスタムタグ部分

<element-details>
  <span slot="element-name">slot</span>
  <span slot="description">A placeholder inside a web
    component that users can fill with their own markup,
    with the effect of composing different DOM trees
    together.</span>
  <dl slot="attributes">
    <dt>name</dt>
    <dd>The name of the slot.</dd>
  </dl>
</element-details>

<element-details>
  <span slot="element-name">template</span>
  <span slot="description">A mechanism for holding client-
    side content that is not to be rendered when a page is
    loaded but may subsequently be instantiated during
    runtime using JavaScript.</span>
</element-details>

JavaScript

customElements.define('element-details',
  class extends HTMLElement {
    constructor() {
      super();
      var template = document
        .getElementById('element-details-template')
        .content;
      const shadowRoot = this.attachShadow({mode: 'open'})
        .appendChild(template.cloneNode(true));
  }
})

5. 感想

6. 参考