🐥
Web Componentsで子要素を取得したい
Web Component で子要素を取得するには slot を使おう
Web Components で子要素を取得するには<slot>
を使う
ElemntWithChildren.ts
class ElementWithChildren extends HTMLElement {
connectedCallback() {
const shadow = this.attachShadow({ mode: "open" });
shadow.innerHTML = `
<div>
<slot></slot>
</div>
`;
}
}
customElements.define("element-with-children", ElementWithChildren);
ts をコンパイルして色々して
index.html
<element-with-children>
<p>子要素だぞ</p>
</element-with-children>
みたいにするとブラウザには
って出る
開発者ツールから DOM を見てみると
っていう変な感じになってる
slot に名前をつけよう
slot に name 属性をつけると、対応するところに挿入してくれる
UserCard.ts
class UserCard extends HTMLElement {
connectedCallback() {
const shadow = this.attachShadow({ mode: "open" });
shadow.innerHTML = `
<div>
Name: <slot name="username"></slot>
</div>
<div>
Name: <slot name="birthday"></slot>
</div>
`;
}
}
customElements.define("user-card", UserCard);
index.html
<user-card>
<span slot="username">John Smith</span>
<span slot="birthday">01.01.2001</span>
</user-card>
connectedCallback 内では this.innerHTML で子要素を取得するのはやめよう
connectedCallback 内では innerHTML で子要素を取得するのは多分あまりよくない
これは以下のような理由から:
DOM は親要素 → 子要素の順にレンダリングされる
<parent>
<child></child>
</parent>
という構成だったら parent のレンダリングは child より先になる
connectedCallback は要素が DOM に挿入されたタイミングで走るけど、そのタイミングでは子要素がまだ作成されていない
<script>
customElements.define(
"user-info",
class extends HTMLElement {
connectedCallback() {
alert(this.innerHTML); // connectedCallbackが走るタイミングではinnerHTMLは空
}
}
);
</script>
<user-info>John</user-info>
setTimeout とかで子要素の作成を待つこともできるけど、それだったら素直に slot を使った方がいい
参考
Discussion