先日 Web Components を構成する技術のひとつである Templates に関するビデオを公開しましたので、解説したいと思います。
なぜ今 Templates なのか
我々開発者にとってテンプレートを使うメリットは、デザイナーとの分業を容易にできる、という点にあります。ウェブサイトを構築する際に利用されるテンプレートというと、以前は PHP や Python の Django, Ruby on Rails をはじめとするサーバー側での実装が主流でした。それがここ数年、ブラウザ側で処理するテンプレート技術が登場し、人気となってきています。
これは HTML5 などオープンウェブ技術の発展により、全体的なアーキテクチャが変わりつつあるためです。サーバーはコンピューターがデータを処理するもの、クライアント側はユーザーがデータを加工するもの、といった分担がより進んでおり、サーバー側で完結していた MVC (Model, View, Controller) がクライアント側とまたがり、より明確な役割を担うべく変遷をしている時期である、と言えるかもしれません。
それに伴い、クライアント側でも MVC のような構成が必要だという機運が高まり、ここ最近は特に AngularJS や Backbone.js, Ember.js といったフレームワークがよく使われるようになってきました。テンプレートを活用できるフレームを利用することで、HTML や CSS といった見た目を担当するデザイナーが、命令的手法 (imparative) より比較的容易な宣言的手法 (declarative) のみに集中してプログラムを記述することでき、チームとしての生産性の向上が期待できます。
ブラウザ側のテンプレートエンジンといえば Mustache.js, Handlebar.js, AngularJS, Backbone.js など、JavaScript で実現するものが人気を博していますが、こういったソリューションにはいくつか解決すべき課題もあります。
div タグを使ったアプローチ
div タグを display:none; として表示されないようにしたものにテンプレートを埋め込み、表示する際にコピーして利用します。このアプローチでは、まだ利用されていない画像などのリソースでもサーバーに取りに行ってしまうため、パフォーマンスが犠牲になるという欠点があります。<div style="display:none;"> <div> <h1>Web Components</h1> <img src="http://webcomponents.org/img/logo.svg"> </div> </div>
script タグを使ったアプローチ
script タグに type="text/javascript" 以外の属性を付与してテンプレートを埋め込み、表示する際にコピーして利用します。このアプローチでは、.innerHTML を使う必要があるため、セキュリティ上のリスクが伴うという欠点があります。<script type="text/template"> <div> <h1>Web Components</h1> <img src="http://webcomponents.org/img/logo.svg"> </div> </script>そこで登場したのが、<template> 要素です。
<template> は Web Components の一翼を担うウェブ標準候補技術で、「自律的に処理されない HTML」をドキュメントに埋め込むことができます。
「自律的に処理されない HTML」とは、下記のような特徴を持ったものです。
scriptタグが含まれても、実際に利用されるまでスクリプトを実行しないimgやvideoといったリソースが含まれても、実際に利用されるまでサーバーにリソースを取りに行かない
Templates の使い方
テンプレートを宣言するには、利用したいテンプレートの HTML を<template> タグで囲んでください。実際に利用するには、JavaScript を使う必要があります。 HTML
<template id="template"> <style> ... </style> <div id="container"> <img src="http://webcomponents.org/img/logo.svg"> </div> </template>
JavaScript
<script>
var template = document.querySelector('#template');
var clone = document.importNode(template.content, true);
var host = document.querySelector('#host');
host.appendChild(clone);
</script>
<div id="host"></div>
実際のコードはこちらでご覧頂けます。
クエリーした
template ノードは document.importNode() を使ってクローンします。2 つめの引数に true を指定することで再帰的にノードの中身もクローンされます。これを別のノードに appendChild() して、はじめて template に命が吹き込まれます。つまり - テンプレートに
scriptタグがある場合、append されてから実行される - テンプレートに画像などのリソースがある場合、append されてから読み込みが始まる
- テンプレートに
styleタグがある場合、append されてから有効になる
注意
ひとつ注意点があります。既存のテンプレートエンジンを使われたことのある方や、既に Polymer をすでにいじっている方であれば、どうやってプレースホルダーを使って変数を埋め込む
<template bind="{{items}}"></template>
繰り返しを表現する
<template repeat="{{item in items}}"></template>
条件分岐をする
<template if="{{item.active}}"></template>
と思われるかもしれません。しかしこれはデータバインディングといって、テンプレートとは区別される別の機能です。そういった機能を自分で実装することなくテンプレートで利用したい場合は、Polymer (TemplateBinding) や x-tags といったフレームワークを利用することをおすすめします。
ブラウザサポート状況
<template> 要素は 2014 年 10 月現在 Chrome, Opera, Safari, Firefox でサポートされています。サポート対象としたいブラウザで利用可能かどうか知りたい場合は、chromestatus.com をご覧下さい。Internet Explorer のような未対応ブラウザで <template> 要素を利用するには platform.js という Polyfill があります。まとめ
いかがでしたでしょうか?Templates は主に Web Components の概念を実現することを視野に考えられた仕様ではありますが、それ以外の利用法もありそうです。ぜひ Templates を活用して、素敵な Web Components を作ってみてください。また、何かユニークな活用法があれば、教えて下さい。Templates についてより詳しく知りたいという方は、下記のドキュメントが参考になると思います。
0 件のコメント:
コメントを投稿