◆ ボタンなどを継承できるようになった

以前 WebComponents を紹介した時 Google の開発者向けのブログには書かれているのに動いてないと書いた機能です
CustomElement を作るときは HTMLElement を継承するのが基本ですが button 要素などすでにある HTML 標準の要素を拡張することも仕様的には可能です
これまで Chrome ではここが動かなかったのですが Chrome 67 で動くようになりました

https://www.chromestatus.com/features/4670146924773376

使い方

使うときは

  • クラスの継承
  • 定義での継承 (extends プロパティ)
  • 使うときの is

の 3 つが必要です

button を継承した a-b タグを作るにはこう書きます

customElements.define("a-b", class extends HTMLButtonElement {}, {extends: "button"})
<button is="a-b"></button>

こうするだけで見た目が button で自分が定義したプロパティやメソッドが使える要素が出来上がります
まぁこの例ではクラスの中身省略したのでただのボタンですけどね

これまでだと HTMLElement を継承した CustomElement の中で button などを持たせておいて自分でプロパティの setter で内側の button 要素のプロパティに反映させて見た目や挙動を変える必要あったので それが不要になるのですごく助かります

足りていないと

使うときには継承した button タグに is 属性に自分で指定した名前を書きます
直接 <a-b> のようにタグを書くと何も起きません
エラーもなく カスタムされないただの要素です
メソッドなどは使えません


クラスの継承を HTMLElement にすると

Illegal constructor: localName does not match the HTML element interface
at new customElements.define.extends

とエラーになります
define メソッドで指定した extends のタグ名とクラスが継承したものが一致しないとコンストラクタ呼び出し時にエラーになります
HTMLElement じゃなく HTMLDivElement などを継承しても同じです


extends を指定せず 「<button is="a-b">aa</button>」 にするとは何もおきません
「<a-b></a-b>」 だと

Uncaught TypeError: Illegal constructor: autonomous custom elements must extend HTMLElement
at new <anonymous>

とエラーです
もし {extends: "div"} としていたらこれでも何も起きません

使うときの タグ名+is が extends と対応しているようです
対応する extends だった場合は define で指定したクラスが呼び出されて そこで extends と 継承したクラスが一致しないとエラーとなっています

要素の作り方

直接 HTML を書くのじゃなく JavaScript で作る場合は createElement または new 演算子で作れます

document.createElement("button", {is: "a-b"})

new (customElements.get("a-b"))