#daiizメモ

Scrapboxに夢中

Polymer 1.0 で作ったカスタムHTMLタグを使う

この記事は、以下の2つの記事の続きです。

前回までは、新しくなったPolymerの様子を少しだけ観察して、オリジナルなHTMLタグを作るところまでやっていました。

目次

【復習】作ったHTMLタグのデモを開く

Polymer 1.0でWeb Componentsをつくるためのseed elementの話や、demoを実行するまでの手順は、上に挙げた2個めの記事に書いています。 これの続きとして書いていきます。

前回作った<price-tax>タグのデモページは、ターミナル上で

$ polyserve

を実行して、ChromeやSafariなどのウェブブラウザでhttp://localhost:8080/components/seed-element/demo/を開くと見ることができます。

商品名に下線を引いてみる

前回までのデモには殆どCSSを書いていなかったので、ここで書き加えてみます。まずは、<price-tax>の作者として、カスタムタグ本体のHTMLにCSSを書く方法です。メニューが表示される<span>には予めid=menuが付いているため、とても簡単で、/price-tax.html の<dom-module>直下に書かれている<style>に、

#menu {
    text-decoration: underline;
}

を追加するだけでOKです。これで、商品名を目立たせることができました。

商品名を太字にしてみる

今度は<price-tax>を利用する人の立場から書きます。利用者はアンダーラインを引くだけでは目立たないと思ったので、さらに商品名の文字を太くしようと考えました。この場合の例です。今度は /demo/index.html を触ります。

Shadow DOM でなく Shady DOM が使われるようになったおかげで、ブラウザで見えている部分は隠蔽されておらず簡単にスタイルを当てることができます。いつも通り、 <head><style>内に

price-tax #menu {
    font-weight: bold;
}

を追記するだけで商品名が太字になります。

新しい商品を追加する

今あるメニューの末尾に新メニュー「ミニサラダ 300円(税別)」を追加してみます。/demo/index.html に直接HTMLタグを書くとすれば、

<price-tax price=300 rate=8 switchable>ミニサラダ</price-tax>

を追記します。 これをJavaScriptで動的に追加する方法は次のとおりです。

window.addEventListener('WebComponentsReady', function (e) {
    var miniSalad = document.createElement('price-tax');

    // 商品名を設定 ★
    Polymer.dom(miniSalad).innerHTML = 'ミニサラダ';

    // 価格と税率を設定
    Polymer.dom(miniSalad).setAttribute('price', 300);
    Polymer.dom(miniSalad).setAttribute('rate', 8);

    // チェックボックスを用意
    Polymer.dom(miniSalad).setAttribute('switchable', true);

    // bodyに追加
    document.querySelector('body').appendChild(miniSalad);
});

やっていることはWebComponentの読み込みが完了したタイミングを見計らって、document.createElement()をして、appendChild()しているだけです。 このコードを<body>の最後に書けばOKです。

ここで、注意することは★の部分です。

NG: miniSalad.innerHTML = 'ミニサラダ';
OK: Polymer.dom(miniSalad).innerHTML = 'ミニサラダ';

NGのようにやってしまうと、<price-tax>内に展開された内容を上書きしてしまいます。上記をやった後のOKとNGの場合について「見たままDOM」を比較してみると、

OK:
<price-tax price="300" rate="8" switchable="true">
    <span id="menu" class="style-scope price-tax">ミニサラダ</span>
    <span id="total" class="style-scope price-tax">324円</span>
    <input type="checkbox" checked="" id="way" class="style-scope price-tax">税込み
</price-tax>

NG:
<price-tax price="300" rate="8" switchable="true">ミニサラダ</price-tax>

のような状態になり、NGの方はチェックボックスも何もかも無くなってしまいます。 OKの方を実行すると、

のように表示されます。

【付録】クイズ

上のようなメニューが表示されているとき、Chrome Developer Toolで以下のJavaScriptを実行するとどのような値が返ってくるでしょうか。 ちなみに、「カルビ盛合せ」の<price-tax>

var calvi = document.querySelectorAll('price-tax')[0];

で取得できます。

Quiz 1.

calvi.children.length;

答え: 注*1

Quiz 2.

Polymer.dom(calvi).children.length

答え: 注*2

Quiz 3.

Polymer.dom(calvi).innerHTML

答え: 注*3

*1:3. [span#menu, span#total, input#way] の 3個です。

*2:0. Shady DOMの<price-tax>はHTML要素を内包していないので 0個です。

*3:カルビ盛合せ