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を用意した」と理解している。ものすごく分かりやすくなって良い方法だと思う。