Web Components の実験 その2

1. このページの目的

Shadow DOM v1: 自己完結型ウェブ コンポーネント  |  Web  |  Google Developers に載っているコードを試してみる。

2. デモその1

<slot> 要素を使う。

コード

HTML

<fancy-tabs>
  <button slot="title">Title</button>
  <button slot="title" selected>Title 2</button>
  <button slot="title">Title 3</button>
  <div>content panel 1</div>
  <div>content panel 2</div>
  <div>content panel 3</div>
</fancy-tabs>

<!-- Using <h2>'s and changing the ordering would also work! -->
<fancy-tabs>
  <h2 slot="title">Title</h2>
  <div>content panel 1</div>
  <h2 slot="title" selected>Title 2</h2>
  <div>content panel 2</div>
  <h2 slot="title">Title 3</h2>
  <div>content panel 3</div>
</fancy-tabs>

JavaScript

customElements.define('fancy-tabs', class extends HTMLElement {
  constructor() {
    super();
    const shadowRoot = this.attachShadow({mode: 'open'});
    shadowRoot.innerHTML = `
      <div id="tabs">
        <slot id="tabsSlot" name="title"></slot>
      </div>
      <div id="panels">
        <slot id="panelsSlot"></slot>
      </div>
    `;
  }
});

実行結果

content panel 1
content panel 2
content panel 3

Title

content panel 1

Title 2

content panel 2

Title 3

content panel 3

実行結果を Chrome DevTools [Elements]パネルで見たところ

メモ

3. デモその2

:hots, :host(<selector>), :host-context(<selector>), ::slotted(<compound-selector>) を使う。

セレクタ 説明
:host
  • ホスト自身を表す。
:host(<selector>)
  • ホストが <selector> に一致する場合に、ホストをターゲットにすることができる。
:host-context(<selector>)
  • コンポーネントまたはそのいずれかの祖先が <selector> に一致する場合に、コンポーネントに一致する。
  • たとえば、<body>の class に指定されたテーマ用クラスに対応するのに使用する。
::slotted(<compound-selector>)
  • <slot> に分散されるノードに一致する。
  • slot に指定された要素が実際にどの位置にレンダリングされたかを問わず、slot に出力された要素をターゲットにすることができる。

コード

HTML

<demo-elm class="blue">
  <h3>Foo</h3>
  <p class="title">
  Hi, <span class="company">Foo</span>
  </p>
  <h4>Bar</h4>
  <p class="memo">
  Hello, <span class="blue">Bar!</span>
  </p>
</demo-elm>

JavaScript

customElements.define('demo-elm', class extends HTMLElement {
  constructor() {
    super();
    const shadowRoot = this.attachShadow({mode: 'open'});
    shadowRoot.innerHTML = `
      <style>
      :host {
        display: block;
        padding: .5em;
        border: 1px solid green;
      }
      :host(.blue) {
        border: 1px solid blue;
      }
      :host-context(.demo) {
        color: green;
        background: #eee;
      }
      ::slotted(h3) {
        margin: 0;
        font-weight: 300;
        color: red;
      }
      ::slotted(.title) {
         color: orange;
      }
      </style>
      <h2>Demo</h2>
      <slot></slot>
    `;
  }
});

実行結果

Foo

Hi, Foo

Bar

Hello, Bar!

メモ

3. メモ

4. 参考