概要
ShadowDOMとは、DOMをカプセル化する技術です。
これを使うことによって他の要素とは独立した(相互に影響しない)DOMを作ることができます。
例えば、「グローバルなCSSをShadowDom内の要素には反映させない」ということが可能です。
基本コード
See the Pen Untitled by masahiro nomura (@masahiroview) on CodePen.
こちらをみるとグローバルなCSS(color:red)がShadowDom内の要素には反映されていないことがわかります。
ShadowDom化する方法
下記の手順で実装します
①wrapper要素にshadowrootを指定
②wrapper要素にinner要素を追加
See the Pen Untitled by masahiro nomura (@masahiroview) on CodePen.
注意点:inner要素はShadowDom化してから追加する必要がある
ちなみに、もともとinner要素が存在する状態で、全体をshadowdom化することはできません。
先述の通り、まずはwrapper要素をshadowrootに指定してから、inner要素を追加する必要があります。
以下のコードがその事例です。
See the Pen Untitled by masahiro nomura (@masahiroview) on CodePen.
もとから存在する要素は表示されず、shadowdom化した後に追加した要素のみが表示されています。
ShadowDom内の要素にCSSを反映させる
JSで個別にCSSを反映する
先述の通り、ShadowDom内の要素にはグローバルなCSSは反映されません。
JSを使ってShadowDom化した要素にCSSをあてることは可能です。
See the Pen shadowdom4 by masahiro nomura (@masahiroview) on CodePen.
CSSではグローバルにはcolor:red !importantが指定されています。
しかし、ShadowDom内の要素にはそれが反映されず、color:blue(JSで別途指定したもの)が反映されていることがわかります。
cssファイルをShadowDomに反映する
以下のようにファイル単位でCSSを設定することも可能です。
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内の要素にイベントハンドラを指定する
クリックイベントの場合は、以下のように実装します。
※ボタンクリックでテキストが赤くなります。
See the Pen Untitled by masahiro nomura (@masahiroview) on CodePen.
まとめ
私がShadowDomを使ってみようと思ったきっかけは、自作Chrome拡張を作ろうとしたのがきっかけでした。
Chrome拡張からサイトに追加した要素が、もともとあるCSSやJSとバッティングしてしまっていたのですが、ShadowDomを使うことによって、バッティングが一切発生しなくなりました。
普通にサイトを作る際にShadowDomうまく使えば、バッティングによる表示崩れも発生しなくなりますし、エラー時の原因特定も簡単になりそうです。
コメント