1. このページの目的
Shadow DOM v1: 自己完結型ウェブ コンポーネント | Web | Google Developers に載っているコードを試してみる。
2. デモその1
<slot>
要素を使う。
コード
<fancy-tabs>
<button slot="title">Title</button>
<button slot="title" selected>Title 2</button>
<button slot="title">Title 3</button>
<div>content panel 1</div>
<div>content panel 2</div>
<div>content panel 3</div>
</fancy-tabs>
<!-- Using <h2>'s and changing the ordering would also work! -->
<fancy-tabs>
<h2 slot="title">Title</h2>
<div>content panel 1</div>
<h2 slot="title" selected>Title 2</h2>
<div>content panel 2</div>
<h2 slot="title">Title 3</h2>
<div>content panel 3</div>
</fancy-tabs>
customElements.define('fancy-tabs', class extends HTMLElement {
constructor() {
super();
const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.innerHTML = `
<div id="tabs">
<slot id="tabsSlot" name="title"></slot>
</div>
<div id="panels">
<slot id="panelsSlot"></slot>
</div>
`;
}
});
- 名前付きslot (name="title") と、名前なしslot が1つずつセットされている。
実行結果
content panel 1
content panel 2
content panel 3
Title
content panel 1
Title 2
content panel 2
Title 3
content panel 3
実行結果を Chrome DevTools [Elements]パネルで見たところ
- もともと用意していた通りのHTMLが表示されている。画面にレンダリングされた順番とは違う。
メモ
- Shadow DOM にセットした「名前付きslot」に該当する要素は、その slot 内に順番に出力される。それ以外の要素は、1番目の「名前なしslot」内に出力されるようだ。
3. デモその2
:hots
, :host(<selector>)
, :host-context(<selector>)
, ::slotted(<compound-selector>)
を使う。
セレクタ | 説明 |
---|---|
:host |
|
:host(<selector>) |
|
:host-context(<selector>) |
|
::slotted(<compound-selector>) |
|
コード
<demo-elm class="blue">
<h3>Foo</h3>
<p class="title">
Hi, <span class="company">Foo</span>
</p>
<h4>Bar</h4>
<p class="memo">
Hello, <span class="blue">Bar!</span>
</p>
</demo-elm>
customElements.define('demo-elm', class extends HTMLElement {
constructor() {
super();
const shadowRoot = this.attachShadow({mode: 'open'});
shadowRoot.innerHTML = `
<style>
:host {
display: block;
padding: .5em;
border: 1px solid green;
}
:host(.blue) {
border: 1px solid blue;
}
:host-context(.demo) {
color: green;
background: #eee;
}
::slotted(h3) {
margin: 0;
font-weight: 300;
color: red;
}
::slotted(.title) {
color: orange;
}
</style>
<h2>Demo</h2>
<slot></slot>
`;
}
});
実行結果
Foo
Hi, Foo
Bar
Hello, Bar!
メモ
- カスタムタグにはデフォルトで
display: inline
がセットされる(display
のデフォルト値はinline
なので)。
3. メモ
HTMLButtonElement
クラスにはattachShadow()
がない。