Web Componentsを試してみた

今回はWeb Componentsを使って実際にコードを書いていきたいと思います。

アイコンと文言がセットになったざーーっくりとしたプロフィール用のテンプレートを例に作っていきます。

いきなりですが、↓が全体のコードになります。 一つ一つ解説を交えながら進めていきます!

<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
  <style>
  </style>
</head>
<body>
  <profile-template></profile-template>
  <profile-template>
    <img src='images/jyojyo.jpg' slot="img" alt=''>
    <p slot="description">よちよち開発よちよち開発よちよち開発よちよち開発</p>
  </profile-template>
  <script>
  class Profile extends HTMLElement {
    static get template(){
      return `
      <style>
        .profile {
          display: flex;
          align-items:center;
          justify-content: space-around;
        }
        .profile_img {
          width:200px;
        }
        img, #img::slotted(*) {
          width:200px;
        }
      </style>
       <div class="profile">
        <p class="profile_img">
          <slot name="img" id="img">
            <img src="images/riki.jpg">
          </slot>
        </p>
        <slot name="description">滑舌の悪いおじさん滑舌の悪いおじさん滑舌の悪いおじさん</slot>
       </div>
    `;
    }
    constructor(){
      super();
      this.attachShadow({
        mode: 'open'
      }).innerHTML = Profile.template;
    }
  }
  customElements.define('profile-template', Profile);
  </script>
</body>
</html>

-------以下から解説-------

class Profile extends HTMLElement {
//省略
}

ここではextends HTMLElementHTMLElement を継承します。

constructor(){
 super();
   this.attachShadow({
     mode: 'open'
   }).innerHTML = Profile.template;
}

attachShadow を利用することでShadow DOMを有効にしています。その後innerHTMLでstyleとHTMLを突っ込んでいます。

<div class="profile">
  <p class="profile_img">
    <slot name="img" id="img">
      <img src="images/riki.jpg">
    </slot>
  </p>
  <slot name="description">
    滑舌の悪いおじさん滑舌の悪いおじさん滑舌の悪いおじさん
  </slot>
</div>

htmlのコードの中にslotという文字があります。 Shadow DOM は、 要素を使用して複数の異なる DOM ツリーを合成します。これを使って自由に独自のマークアップを入れることができます。

customElements.define('profile-template', Profile);

customElements.defineでCustom Elementを定義しています。 第一引数が実際に使用する要素のタグ名で、第二引数はクラス名になります。ブラウザにCustom Elementだと認識させるためにタグ名はダッシュをつけます。

ブラウザに表示させた結果はこちらになります。(スタイルがイケてなくてすみません。。。)

f:id:top_men:20180401040354p:plain

まだ一部のブラウザ標準でまだ使用することはできないので、未対応のブラウザにも Web Componentsを使用できるためのPolyllを導入することが必要になると思います。

github.com