開発者ドキュメント

あなたの最初のカスタム要素

では、Webコンポーネントについて学び、独自のカスタムHTMLタグを作成することに興味がありますか? この投稿では、 CustomElementsShadowDOMを使って手を出すための基本的な構文と概念について説明します。

ばかげたものを作りますスタイル付きのタイトルを単純にスタンプするカスタム要素。 あまり有用ではありませんが、いくつかの開始概念を示すのに役立ちます。

入門

最初に、カスタム要素に関するすべて(スタイルルール、マークアップ、ES6クラス定義)を含む別のJavaScriptファイルを作成し、最後にカスタム要素を登録します。 カスタム要素を使用するHTMLファイルでは、そのJavaScriptファイルを含めるだけで、ページで新しいタグの使用を開始できます。

すべてをIIFEでラップして、適切な測定を行いましょう。

my-title.js
(function() {
  // the good stuff goes here
})();

次に、HTMLElementを拡張するカスタム要素のクラスを定義しましょう。

(function() {
  class MyTitle extends HTMLElement {
    connectedCallback() {
      this.innerHTML = `
        <style>
          h1 {
            font-size: 2.5rem;
            color: hotpink;
            font-family: monospace;
            text-align: center;
            text-decoration: pink solid underline;
            text-decoration-skip: ink;
          }
        </style>
        <h1>Hello Alligator!</h1>
      `;
    }
  }

  window.customElements.define('my-title', MyTitle);
})();

注意すべき点がいくつかあります。

このような単純なカスタム要素を使用すると、 customElements.define の呼び出しで、クラスを匿名クラスとして直接定義することもできます。

(function() {
  window.customElements.define(
    'my-title',
    class extends HTMLElement {
      connectedCallback() {
        this.innerHTML = `
          <style>
            h1 {
              font-size: 2.5rem;
              color: hotpink;
              font-family: monospace;
              text-align: center;
              text-decoration: pink solid underline;
              text-decoration-skip: ink;
            }
          </style>
          <h1>Hello Alligator!</h1>
        `;
      }
    }
  );
})();

すべてがJavaScriptに含まれており、スタンドアロンのHTMLマークアップがないことに気付くでしょう。 これは、おそらく残念ながら、 HTMLインポートが水中で死んでいるように見えるためです。Webコンポーネントの今後の道は、ES6文字列リテラルを使用してJavaScriptでマークアップとスタイルを定義することです。

ShadowDOM

上記の例はすべてうまくいっていますが、大きな問題が1つあります。それは、スタイルがカスタム要素にスコープされていないことです。 つまり、ページ上のすべての h1 タグは、下線付きのホットピンクになります。 このコンポーネントのスタイルがその外界に影響を与えないようにするためのアドホックな解決策は、マークアップをdivのようなものの中にラップしてから、ラッパーのみをターゲットとするセレクターでスタイルを適用することです。

this.innerHTML = `
  <style>
    .wrap-my-title h1 {
      font-size: 2.5rem;
      color: hotpink;
      font-family: monospace;
      text-align: center;
      text-decoration: pink solid underline;
      text-decoration-skip: ink;
    }
  </style>
  <div class="wrap-my-tile">
    <h1>Hello Alligator!</h1>
  </div>
`;

マークアップのどこかにwrap-my-titleを持つ別の要素がある場合、それは素晴らしいことではなく、絶対確実ではありません。 さらに、 h1 のような単純なCSSセレクターを使用できれば、パフォーマンスが向上し、はるかに優れたものになります。 これがShadowDOM[X28X]の出番です。 Shadow DOMを使用すると、スタイルをカスタム要素にスコープして、ブリードアウトしないようにすることができます。

Shadow DOMを使用するには、 shadow root を要素にアタッチしてから、シャドウルート内の要素のマークアップを定義します。

(function() {
  class MyTitle extends HTMLElement {
    constructor() {
      super();

      this.attachShadow({ mode: 'open' });
      this.shadowRoot.innerHTML = `
        <style>
          h1 {
            font-size: 2.5rem;
            color: hotpink;
            font-family: monospace;
            text-align: center;
            text-decoration: pink solid underline;
            text-decoration-skip: ink;
          }
        </style>
        <h1>Hello Alligator!</h1>
      `;
    }
  }

  window.customElements.define('my-title', MyTitle);
})();

注意すべき点がいくつかあります。

Shadow DOMを使用すると、ブラウザのコンソールでマークアップがどのように表示されるかを次に示します。

代替構文

template 要素を作成し、その innerHTML を設定してから、テンプレートのコンテンツを新しい子としてシャドウルートに複製することでも同じ結果を得ることができます。

(function() {
  const template = document.createElement('template');

  template.innerHTML = `
      <style>
        h1 {
          font-size: 2.5rem;
          color: hotpink;
          font-family: monospace;
          text-align: center;
          text-decoration: pink solid underline;
          text-decoration-skip: ink;
        }
      </style>
      <h1>Hello Alligator!</h1>
  `;

  class MyTitle extends HTMLElement {
    constructor() {
      super();

      this.attachShadow({ mode: 'open' });
      this.shadowRoot.appendChild(template.content.cloneNode(true));
    }
  }

  window.customElements.define('my-title', MyTitle);
})();

使用法

カスタム要素の使用は、スクリプトファイルをページに追加してから、他の通常のHTML要素と同じように要素を使用するのと同じくらい簡単です。 ただし、カスタム要素には常に終了タグが必要であることに注意してください。

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <script src="./my-counter.js"></script>
</head>

  <body>
    <my-title></my-title>
  </body>

</html>

私たちの要素は完全に本番環境に対応しているわけではないことに注意してください。 現在のように、この要素はいくつかの最新のブラウザでのみ機能します。 ES6クラスや文字列リテラルなどの全面的にサポートされていないJavaScript機能用のBabelのようなトランスパイラーを介してコードを実行し、カスタム要素とシャドウDOMにポリフィルを使用する必要があります。 別の投稿で、Webコンポーネントのポリフィルの使用について説明します。

モバイルバージョンを終了