🧩
Web Components を実装した
Web Components を実装しました。Custom elements と Shadow DOM を使いました。
customElements.define("my-element", class extends HTMLElement {
constructor() {
super();
this.attachShadow({mode: "open"});
}
attributeChangedCallback() {
this.#_attributeChangedCallback();
}
connectedCallback() {
this.#_connectedCallback();
}
});
Custom elements
CustomElementRegistry.define
新しい要素が登録できます。
ここではmy-element
要素を登録しています。(要素名には多少の制限があるようです)
The lifecycle callbacks
要素のライフサイクルに応じて起動できます。
#attr;
#attr_old;
static get observedAttributes() {
return ["my-attr"];
}
attributeChangedCallback(name, oldValue, newValue) {
if ("my-attr" !== name) {
return;
}
this.#attr = newValue;
this.#attr_old = oldValue;
}
#connected = false;
connectedCallback() {
if (this.#connected) {
return;
}
this.#_init();
(new MutationObserver(this.#_init)).observe(this, this.#_options);
this.#connected = true;
}
attributeChangedCallback
observedAttributes
で指定した属性が追加、削除、変更されるたびに実行されます。
ここではmy-attr
属性を指定しています。古い値oldValue
と新しい値newValue
をそれぞれ#attr_old
プロパティと#attr
プロパティに設定します。
connectedCallback
要素がDOMに追加されるたびに実行されます。
ここでは最初に追加されたときにMutationObserver.observe
を呼び出しています。要素が変更されたときにコールバック関数this.#_init
を呼び出します。
また最初にNode.childNodes
等を使いたいときはconstructor
よりもconnectedCallback
で使うようにしています。constructor
ではエラーを吐くことがあったので。
Shadow DOM
this.attachShadow({mode: "open"}).appendChild(document.createElement("style")).textContent = `:host {
display: block;
}`;
const style = document.createElement("link");
style.rel = "stylesheet";
style.href = "style.css";
this.shadowRoot.appendChild(style);
Element.attachShadow
Shadow DOM が追加できます。Element.shadowRoot
への参照を返します。
Element.shadowRoot
ShadowRoot
オブジェクトです。
ここでは Shadow DOM にスタイルシートを追加しています。
Shadow DOM は(基本的に)外のスタイリングに影響しない、されないようです。
- 継承はするようです
- CSS custom propertiesも継承するようです
:host
擬似クラス
Shadow host が選択できます。
ここではmy-element
要素のスタイルに display: block
を加えています。
::part
擬似要素
Shadow tree の内の要素が選択できます。
Discussion