templatesとslots

概要

webコンポーネントのshadow DOMとしてポピュラーに使用されている

templatesについて

より簡単にマークアップを使い回す事ができる。

template要素とその中身はDOM内にはレンダーされないが、 JavaScriptを通して参照することが可能。

簡単なtemplate例

<template id="my-paragraph">
    <p>My paragraph</p>
</template>

DOMに追加することで表示される。

// templateタグを取得
let template = document.getElementById('my-paragraph')
// 中身を取得
let templateContent = template.content
// DOMに追加
document.body.appendChild(templateContent)

Webコンポーネントに使用する

my-paragraph 要素を定義する

class MyParagraph extends HTMLElement {
    constructor() {
        super()
        let template = document.getElementById('my-paragraph')
        let templateContent = template.content
        const shadowRoot = this.attachShadow({mode: 'open'})
            .appendChild(templateContent.cloneNode(true))
    }
}

customElement.define('my-paragraph', MyParagraph)
  • templateContent.cloneNode(true): テンプレートタグの子孫も含めてクローンする

テンプレート内の<style>要素の定義はカプセル化され、その他のDOMに影響を与えない。

<template id="my-paragraph">
  <style>
    p {
      color: white;
      background-color: #666;
      padding: 5px;
    }
  </style>
  <p>My paragraph</p>
</template>
<p>This is standard p element.</p>
<my-paragrah></my-paragrah>

gist

f:id:yossan2:20200926161833p:plain

slots フレキシブルなテンプレートを作る

slots 要素を使うことで宣言的な方法でテンプレートの中身を変更できる。

name 属性によって識別する。

<template id="my-paragraph">
  <style>
    p {
      color: white;
      background-color: #666;
      padding: 5px;
    }
  </style>
  <p>My paragraph</p>
  <p><slot name="my-text">My default text</slot></p>
</template>
<p>This is standard p element.</p>
<my-paragraph></my-paragraph>

デフォルトのパラグラフが表示される。

f:id:yossan2:20200926161905p:plain

slot属性を指定して、<slot> 要素と入れ替える。

<p>This is standard p element.</p>
<my-paragraph>
  <span slot="my-text">Let's have some different text!</span>
</my-paragraph>

gist

f:id:yossan2:20200926161920p:plain

<my-paragraph>
  <ul slot="my-text">
    <li>Let's have some different text!</li>
    <li>In a list!</li>
  </ul>
</my-paragraph>

f:id:yossan2:20200926161934p:plain

参照

https://developer.mozilla.org/en-US/docs/Web/Web_Components/Using_templates_and_slots