概要
ShadowDOMとは、DOMをカプセル化する技術です。
これを使うことによって他の要素とは独立した(相互に影響しない)DOMを作ることができます。
例えば、「グローバルなCSSをShadowDom内の要素には反映させない」ということが可能です。
基本コード
こちらをみるとグローバルなCSS(color:red)がShadowDom内の要素には反映されていないことがわかります。
ShadowDom化する方法
下記の手順で実装します
①wrapper要素にshadowrootを指定
②wrapper要素にinner要素を追加
注意点:inner要素はShadowDom化してから追加する必要がある
ちなみに、もともとinner要素が存在する状態で、全体をshadowdom化することはできません。
先述の通り、まずはwrapper要素をshadowrootに指定してから、inner要素を追加する必要があります。
以下のコードがその事例です。
もとから存在する要素は表示されず、shadowdom化した後に追加した要素のみが表示されています。
ShadowDom内の要素にCSSを反映させる
JSで個別にCSSを反映する
先述の通り、ShadowDom内の要素にはグローバルなCSSは反映されません。
JSを使ってShadowDom化した要素にCSSをあてることは可能です。
CSSではグローバルにはcolor:red !importantが指定されています。
しかし、ShadowDom内の要素にはそれが反映されず、color:blue(JSで別途指定したもの)が反映されていることがわかります。
cssファイルをShadowDomに反映する
以下のようにファイル単位でCSSを設定することも可能です。
1 2 3 4 5 6 7 8 9 10 | const app = document.getElementById("shadowWrapper"); //①wrapper要素にshadowrootを指定 shadowRoot = app.attachShadow({ mode: "open" }); //②wrapper要素にinner要素を追加 $(shadowRoot).append("<p>shadowdomのテキスト</p>"); //③テキストのスタイルを設定 const link = document.createElement("link"); link.rel = "stylesheet"; link.href ="style.css"; $(shadowRoot).append(link); |
ShadowDom内の要素にイベントハンドラを指定する
クリックイベントの場合は、以下のように実装します。
※ボタンクリックでテキストが赤くなります。
まとめ
私がShadowDomを使ってみようと思ったきっかけは、自作Chrome拡張を作ろうとしたのがきっかけでした。
Chrome拡張からサイトに追加した要素が、もともとあるCSSやJSとバッティングしてしまっていたのですが、ShadowDomを使うことによって、バッティングが一切発生しなくなりました。
普通にサイトを作る際にShadowDomうまく使えば、バッティングによる表示崩れも発生しなくなりますし、エラー時の原因特定も簡単になりそうです。
コメント