Web Componentsを試してみる

0 件のコメント
【Web ComponentsとPolymerをさわってみる。】の続きですが、
今回はWeb Componentsで軽くサンプル作りつつポイントを書いていきたいと思います。
Polymerについては触れないです。

今回サラっと触っているのが、下記のAPIです。
Custom Elements
HTML Imports
HTML Templates
Shadow DOM

ちなみに、筆者の実行環境は【Google Chromeのバージョン 37.0.2062.120】です。 

サンプルコード

このコードは、ホバーすることで色の変わる【x-sample】というタグを作っています。
そして、コード中にある、8つの【※注目※】については下部で説明します。
<!DOCTYPE HTML>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title></title>
</head>
<body>
<style type="text/css">
/* ※注目1※ */
:unresolved {
visibility: hidden;
}
</style>
<link rel="import" href="sample.html">
<x-sample></x-sample>
<x-sample2></x-sample2>
<sample></sample>
</body>
</html>
view raw index.html hosted with ❤ by GitHub
<script src="sample.js"></script>
<template id="x-sample">
<!-- ※注目2※ -->
<link rel="stylesheet" href="sample.css">
<style type="text/css">
[is="color"] {
transition: color 400ms ease-in-out, background 400ms ease-in-out;
background: red;
color: black;
}
[is="color"]:hover {
background: black;
color: red;
}
</style>
<section class="x-sample" is="color">
test
</section>
</template>
<script>
(function() {
// ※注目3※
var currentScript = document._currentScript || document.currentScript;
var doc = currentScript.ownerDocument;
var prototype = Object.create(HTMLElement.prototype, {
createdCallback: {
value: function() {
// ※注目4※
console.log("createdCallback");
var t = doc.querySelector('#x-sample');
var clone = doc.importNode(t.content, true);
this.createShadowRoot().appendChild(clone);
}
},
attachedCallback: {
value: function() {
// ※注目5※
console.log("attachedCallback");
}
},
detachedCallback: {
value: function() {
// ※注目6※
console.log("detachedCallback");
}
},
attributeChangedCallback: {
value: function() {
// ※注目7※
console.log("attributeChangedCallback");
}
}
});
// ※注目8※
document.registerElement('x-sample', {prototype: prototype});
})();
</script>
view raw sample.html hosted with ❤ by GitHub
console.log("sample.js");
view raw sample.js hosted with ❤ by GitHub


  • 注目1
:unresolved
というCSSの擬似クラスが適用されるのは、Custom Elementsが未定義の場合。
サンプルコードを実行すると、<x-sample>は適用されておらず、<x-sample2>は適用されている。
<sample>は命名規則からズレているからか、適用されず。
「:unresolved」の使いドコロは、未定義状態の要素が見えてしまうことによって起こる表示のチラツキを抑えるとかになります。

  • 注目2
<link rel="stylesheet" href="sample.css">
でcssを読み込もうとしているが、読み込みされない。
http://www.w3.org/TR/shadow-dom/#inert-html-elements
図. 通信さえ走らない
直書きすれば問題はないが、それでは色々と辛いので下記のような手法がある。
Vulcanizeで減らすHTML ImportsのHTTPリクエスト

また、Polymerの場合は良しなにインライン展開してくれるらしい。

  • 注目3
ここでdocumentを参照すると、インポートした側の参照になってしまう。
インポートされる側を参照できるようにしておく。

  • 注目4〜7
4〜7で指定しているコールバックの実行タイミングは下記です。
実際に、Developer Toolsのconsoleから実行してみればよく分かると思います。
// 要素が作成されたタイミング
var sample = document.createElement('x-sample');
⇒ createdCallback 
// 要素の属性が変更されたタイミング
sample.id = "sample";
⇒ attributeChangedCallback 
// 要素がDOMツリーへ挿入されるタイミング
document.body.appendChild(sample);
⇒ attachedCallback 
// 要素がDOMツリーから削除されるタイミング
document.body.removeChild(sample);
⇒ detachedCallback

  • 注目8
Custom Elementsで使用できるタグの名前には、ハイフンが必須です。
下記の場合にはこんなエラーに。
document.registerElement('sample')
SyntaxError: Failed to execute 'registerElement' on 'Document': Registration failed for type 'sample'. The type name is invalid.

終わりに

Web Componentsネタは、ちょいちょい書くかもです!

以上!

0 件のコメント :

コメントを投稿