ShadowDOMの基本と使い方の解説

概要

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うまく使えば、バッティングによる表示崩れも発生しなくなりますし、エラー時の原因特定も簡単になりそうです。

コメント

タイトルとURLをコピーしました