カスタム要素を使用する

はじめに

ウェブには表現が非常に欠けています。どういうことかを理解するには、Gmail のような「最新」のウェブアプリを覗いてみましょう。

Gmail

<div> スープはモダンな雰囲気ではありません。それでも、Google はこのようにしてウェブアプリを構築しています。悲しい。 当社のプラットフォームにもっと求めるべきではないでしょうか?

性的なマークアップ。やってみよう

HTML はドキュメントを構造化するための優れたツールですが、その語彙は、HTML 標準で定義されている要素に限定されています。

Gmail のマークアップが厄介でなかったらどうなるでしょうか。もしそれが美しいものだったら、

<hangout-module>
    <hangout-chat from="Paul, Addy">
    <hangout-discussion>
        <hangout-message from="Paul" profile="profile.png"
            profile="118075919496626375791" datetime="2013-07-17T12:02">
        <p>Feelin' this Web Components thing.
        <p>Heard of it?
        </hangout-message>
    </hangout-discussion>
    </hangout-chat>
    <hangout-chat>...</hangout-chat>
</hangout-module>

さわやかな気分です。このアプリも大いに意味があります。有益で、理解しやすい、そして何よりもメンテナンス可能です。宣言型バックボーンを調べるだけで その処理が正確に理解できるでしょう

ご利用にあたって

カスタム要素を使用すると、新しいタイプの HTML 要素を定義できます。この仕様は、Web Components に含まれるいくつかの新しい API プリミティブの一つですが、おそらく最も重要な点です。カスタム要素によって機能が解放されない限り、ウェブ コンポーネントは存在しません。

  1. 新しい HTML/DOM 要素を定義する
  2. 他の要素から拡張する要素を作成する
  3. カスタム機能を 1 つのタグに論理的にバンドルする
  4. 既存の DOM 要素の API を拡張する

新しい要素の登録

カスタム要素は document.registerElement() を使用して作成します。

var XFoo = document.registerElement('x-foo');
document.body.appendChild(new XFoo());

document.registerElement() の最初の引数は、要素のタグ名です。名前にはダッシュ(-)を含める必要があります。たとえば、<x-tags><my-element><my-awesome-app> はすべて有効な名前ですが、<tabs><foo_bar> は無効です。この制限により、パーサーはカスタム要素と通常の要素を区別できるようになりますが、新しいタグが HTML に追加されたときの上位互換性も確保されます。

2 番目の引数は、要素の prototype を記述するオブジェクトです(省略可)。ここで、カスタム機能(公開プロパティやメソッドなど)を要素に追加します。 詳しくは後ほど説明します

デフォルトでは、カスタム要素は HTMLElement を継承します。したがって、前の例は次のものと同じです。

var XFoo = document.registerElement('x-foo', {
    prototype: Object.create(HTMLElement.prototype)
});

document.registerElement('x-foo') を呼び出すと、ブラウザに新しい要素について学習させ、<x-foo> のインスタンスの作成に使用できるコンストラクタを返します。コンストラクタを使用しない場合は、要素をインスタンス化する他の方法を使用することもできます。

要素の拡張

カスタム要素を使用すると、既存の(ネイティブ)HTML 要素や他のカスタム要素を拡張できます。要素を拡張するには、継承元の要素の名前と prototyperegisterElement() に渡す必要があります。

ネイティブ要素を拡張する

標準の Joe <button> に不満があるとします。その機能を強化して「メガボタン」にしたいと考えています。<button> 要素を拡張するには、HTMLButtonElementprototype と、要素の名前 extends を継承する新しい要素を作成します。この場合、"button":

var MegaButton = document.registerElement('mega-button', {
    prototype: Object.create(HTMLButtonElement.prototype),
    extends: 'button'
});