Polymer 1.0 の勉強を始めてみようと思う。
最近触っていなかったから、ひとまず思い出すために古いバージョン(v0.5)のPolymerで書いたscrollHeaderPanelと、新バージョン(v1.0)のものを見比べてみた。
名称が変わっていた
バージョンが変わっても、ほぼ同じ挙動をするelementだが、名称が変更になっていた。
- ~ v0.5:
core-scroll-header-panel - v1.0 ~:
paper-scroll-header-panel
paper-グループに入っていた。
要素を使ってみる
まずは、これまでのバージョンでの使用法。例として、miilClientのコードを参考に書くとこんな感じ。
<core-scroll-header-panel condenses>
<core-toolbar class=tall>
<img src="icon.png" style="width:40px; height:40px">
<div class="bottom indent title">scrollHeader</div>
</core-toolbar>
<div id="contents">
(略)
</div>
</core-scroll-header-panel condenses>
いい感じ。scrollHeaderPanelの上段にcore-toolbarを配置し、この中にアイコンと、タイトルを表示している。 下段にはメインのdiv #contentsを置いている。
続いて新バージョンの方法で書いてみる。ここでは省略してしまったCSSやJSなどを含めたコードサンプルは、sandbox/Polymer/scrollHeader at master · daiiz/sandbox · GitHub に置いてあります。
<paper-scroll-header-panel condenses>
<paper-toolbar class="tall">
<img src="icon.png" style="width:40px; height:40px;">
<div class="bottom indent title">scrollHeader</div>
</paper-toolbar>
<div id="contents">
(略)
</div>
</paper-scroll-header-panel>
見た目
スクリーンショットは、以下のようになる。上にスクロールするすると、ヘッダー部分がグインと狭くなって、メインのContents領域が目一杯広がって良い。
見た目では、どちらのバージョンでもほぼ同じだった。
裏側
Chrome Dev Toolでレンダリングの状態を見てみると大きな違いがあった。まずは、古い方:
v0.5
ここでの一番のポイントは、#shadow-rootがあること。shadow-rootのもとに含まれるDOMはShadow DOMと呼ばれ、ここは「影の世界」ということなので、グローバルな領域(通常のDOMの世界)からは参照できないようになっている。なので、
document.querySelector('#mainContainer');
を実行しても、確かにnullが返ってくる。
core-scroll-header-panelやcore-toolbarが読み込まれると、これらはShadow DOMとしてdivなどを創り、この影の世界をブラウザが解釈してブラウザ画面に表示している。
続いて、新しい方を見てみる:
v1.0
これを見たときの最初の感想は「あれれ、丸見え」だった。#shadow-rootは無く、ブラウザに表示されているものはすべて通常のDOMとして描かれていた。こんな状態なので、もちろん
というふうにして要素を取得することもできる。これだとshadow-rootに隠されていたことに比べて、styleを当てたりすることが簡単になった。 でも、「不必要なことは見せない」「見なくて良い」というWeb Compositionsのメリットが失われてしまったよう感じる。
そこで、Shady DOM
Polymer 1.0 からは「Shady DOM」という新しい考え方が導入された。この技術により、まだShadow DOMをサポートしていないブラウザにおいても軽快に動作をWeb Componentを作れるようになるらしい。
先ほどの中身が丸見えになってしまっていたpaper-scroll-header-panelの例だが、これをShady DOM APIを下記のように使って覗いてみた。
Polymer.dom(scrollHeaderPanel).children;
これを実行すると、
のようになった。最後に得られたarrayOfNodesは、まさに最初の方の「要素を使ってみる」の節で書いた2つの要素が展開されたものである。
つまり、
var scrollHeaderPanel = document.querySelector('paper-scroll-header-panel');
としたときに、
scrollHeaderPanel.childrenとすれば、いま、ブラウザ上で見えているDOMの世界が素直に得られる。(見たままDOM)- Shady DOM APIを用いて
Polymer.dom(scrollHeaderPanel).childrenとしたときには、カプセル化された世界観のDOMが得られる。また、これで得られる要素は実際にブラウザに表示されているNodeである。
ということだろうか。
今のところ「新しいPolymerでは、見た目では嘘をつかず(影に隠さず)、代わりにブラウザで見えていない本当のカプセル化されたDOM構造を取得するAPIを用意した」と理解している。ものすごく分かりやすくなって良い方法だと思う。