メニュー

Web Componentsを使ってみよう!

エンジニアブログ

記事投稿 | 2014.06.30

Web Componentsを使ってみよう!

初めまして、TOPGATEの @yukinasu です。
今回はウェブアプリケーションのフロントエンド開発において革命的な技術として注目され、現在仕様策定が進んでいるWeb Componentsについて紹介します。

Web Componentsとは

Web Componentsとは、開発者がHTMLに独自の要素を定義できる仕組みです。
例えば、次のTOPGATEボタンはクリックすると「TOPGATE」というアラートが表示される簡単なボタンです。このボタンを既存のHTMLで記述すると、

TOPGATE

#!html
	<span id="tgButton">TOPGATE</span>
	<style>
	    #tgButton {
	        color: white;
	        background-color: red;
	        padding: 10px;
	        font-family: "Arial Black", arial-black;
	        display: inline-block;
	        border: 5px solid white;
	        cursor: pointer;
	    }
	</style>
	<script>
	    var tgButton = document.getElementById("tgButton");
	    tgButton.addEventListener("click", function(e) {
	        alert("TOPGATE");
	    });
	</script>
	

このようになります。
Web Conponentsを用いると、

#!html
	<tg-button>TOPGATE</tg-button>
	

HTMLに記述するのはこれだけです。HTMLがとてもスッキリしました。
Web ComponentsがUIパーツの構成要素であるHTMLマークアップ、CSS、JavaScriptをコンポーネント化し、<tg-button>要素として定義しているのです。

Web Componentsの特徴

Web Componentsには次のような特徴があります。

  • 既存のHTML、CSS、JavaScriptの知識の延長で作成できる
  • UIパーツをHTMLの独自要素として定義できる
  • UIパーツの内部構造を外から見えなくする
  • UIパーツがカプセル化されるため、内容が変更されても、外部に影響を与えない
  • 再利用性が高い

Web Componentsを構成する技術

Web Componentsは大きく分けて4つ技術から成り立っています。

  • Templates
  • Shadow DOM
  • Custom Elements
  • HTML Imports

Templates以外は2014年6月現在、まだ仕様策定中であり、W3C Editor’s Draftなどで日々最新の仕様が検討されています。
Templatesに関しては2014年3月に仕様策定が完了し、正式にHTML5の仕様として追加されました。 現在の策定状況はW3C Web Components Current Statusで確認できます。

それでは、各技術を説明しながら、次のステップで<tg-button>要素を作成していきます。

  1. Templatesを用いて、<template>要素にHTMLマークアップ、スタイルを定義し、テンプレートを作成する
  2. Shadow DOMを用いて、テンプレートの内容をカプセル化する
  3. Custom Elementsを用いて、カプセル化したテンプレートを<tg-button>要素として定義する
  4. HTML Importsを用いて作成した<tg-button>要素を別ドキュメントに読み込む

Templates

Templatesは文字通りUIパーツのテンプレートです。
<template>要素にUIパーツのHTMLマークアップ、スタイルを定義します。

次のソースコードはTOPGATEボタンのHTMLマークアップ、スタイルをテンプレート化したものです。

#!html
	<template id="tgButtonTemplate">
	    <style>
	        #tgButton {
	            color: white;
	            background-color: red;
	            padding: 10px;
	            font-family: "Arial Black", arial-black;
	            display: inline-block;
	            border: 5px solid white;
	            cursor: pointer;
	        }
	    </style>
	    <span id="tgButton">TOPGATE</span>
	</template>
	

<template>要素で囲まれたコンテンツは次のような特徴を得ます。

  • コンテンツがアクティベートされるまで、自律動作せず、レンダリングされない。
  • コンテンツがアクティベートされるまで、スクリプトの実行、画像やオーディオはロードされない。
  • コンテンツはドキュメント内に存在しないものとして扱われ、メインページで行う docoment.getElementById() または querySelecor()<template>の子ノードを取得できない。
  • テンプレートは<head>,<body> または <frameset>内なら何処でも置くことができ、その中におけるコンテンツなら何を置いても構わない。

Templatesに関する詳しい仕様は次のサイトが参考になります。

Shadow DOM

Shadow DOMはDOMツリーをカプセル化し、ページの他の部分からDOMツリーを分離することができます。
既存のHTML、CSSにはスコープの概念は存在しませんでしたが、Shadow DOMを用いることでHTML、CSSにおいてもスコープが使用可能となります。

次のソースコードはTOPGATEボタンのテンプレートにShadow DOMよるカプセル化を行いました。

#!html
	<template id="tgButtonTemplate">
	    <style>
	        #tgButton {
	            color: white;
	            background-color: red;
	            padding: 10px;
	            font-family: "Arial Black", arial-black;
	            display: inline-block;
	            border: 5px solid white;
	            cursor: pointer;
	        }
	    </style>
	    <span id="tgButton">TOPGATE</span>
	</template>
	
	<div id="host">yukinasu</div>
	
	<script>
	    var host = document.getElementById("host");
	    var root = host.createShadowRoot();
	    var template = document.getElementById("tgButtonTemplate");
	    root.appendChild(document.importNode(template.content, true));
	    root.addEventListener("click", function(e) {
	        alert("TOPGATE");
	    });
	</script>
	

Shadow DOMには次のような特徴があります。

  • UIパーツのマークアップをShadow Tree(既存のDOMツリーとは別次元のDOMツリー)として作成できる
  • Shadow Treeはカプセル化され、外部のCSS、JavaScriptの影響を受けない
  • Shadow Tree内のCSS、JavaScriptも外部に影響しない

Shadow DOMに関する詳しい仕様は次のサイトが参考になります。

Custom Elements

Custom Elementsは開発者独自のHTML要素を作成することができます。
それだけではなく、他のHTML要素を継承したHTML要素の作成や既存のHTML要素を拡張することもできます。

次のソースコードはTOPGATEボタンのテンプレートにShadow DOMよるカプセル化を行い、更にCustom Elementsで独自要素として定義しています。

#!html
	<template id="tgButtonTemplate">
	    <style>
	        #tgButton {
	            color: white;
	            background-color: red;
	            padding: 10px;
	            font-family: "Arial Black", arial-black;
	            display: inline-block;
	            border: 5px solid white;
	            cursor: pointer;
	        }
	    </style>
	    <span id="tgButton">TOPGATE</span>
	</template>
	
	<script>
	    var TgButtonPrototype = Object.create(HTMLElement.prototype);
	    TgButtonPrototype.createdCallback = function() {
	        var template = document.getElementById("tgButtonTemplate");
	
	        var root = this.createShadowRoot();
	        root.appendChild(document.importNode(template.content, true));
	
	        root.addEventListener("click", function(e) {
	            alert("TOPGATE");
	        });
	    };
	
	    var TgButton = document.registerElement("tg-Button", {
	        prototype: TgButtonPrototype
	    });
	</script>
	
	<tg-button>yukinasu</tg-button>
	

Custom Elementsには次のような特徴があります。

  • Custom Elementsの名称には「-」(ハイフン)を含んでいる必要がある
  • 4つのタイミングでイベントが発生し、ライフサイクルコールバックメソッドと呼ばれるコールバックメソッドを設定することができる。
    • createdCallback – Custom Elementsのインスタンスが生成されたタイミング
    • attachedCallback – Custom ElementsのインスタンスがHTMLに追加されたタイミング
    • detachedCallback – Custom ElementsのインスタンスがHTMLから削除されたタイミング
    • attributeChangedCallback – インスタンスの属性が追加・削除・更新されたタイミング

Custom Elementsに関する詳しい仕様は次のサイトが参考になります。

HTML Imports

HTML Importsは別ファイルとして作成されたHTMLドキュメントを読み込み、再利用するための仕組みです。
Web Componentsでは作成したCustom Elementsをインポートするために利用されます。

例えば、上記の<tg-button>を定義したソースコードをtgButton.htmlというHTMLファイルにした場合、このファイルを読み込むためには読み込み元のHTMLに次の様に記述します。

#!html
	<link rel="import" href="tgButton.html">
	

HTML Importsには次のような特徴があります。

  • 別ドメインからコンテンツをロードする場合はCORSに対応している必要がある
  • 同じURLからのimportは、取得もパースも一度しか実行されない
  • import内のscriptは順番に実行されますが、メインドキュメントのパースはブロックしない
  • scriptは読み込まれると同時に実行されるが、CSSやマークアップは明示的に読み込み元に追加しなければならない

HTML Importsに関する詳しい仕様は次のサイトが参考になります。

ブラウザ対応について

Web Componentsはまだ仕様策定中であり、Polyfillを使用せずに利用できるブラウザが限られています。
ですが、Googleが開発しているPolymerやMozillaが開発しているX-TagなどのWeb ComponentsのフレームワークにはPolifillが含まれており、未対応のブラウザでもWeb Componentsを利用することができます。

次のサイトで現在の各ブラウザの対応状況を確認することができます。

まとめ

Web Componentsはまだまだ現場の第一線で活用できるような成熟した技術ではありませんが、数年後にはフロントエンド開発の標準技術となりうるポテンシャルを十分に秘めています。
Custom ElementsではWeb Componentsで作成したUIパーツが公開され、徐々にその数を増やしています。

今回はさわり程度しか書くことができませんでしたが、Web Componentsはとても奥が深いです。
この記事を読んで少しでもWeb Componentsに興味を持ってもらえればいいなと思います。

それでは!

PAGE TOP