コンテンツにスキップ

HTML/Shadow DOM

出典: フリー教科書『ウィキブックス(Wikibooks)』

Shadow DOM

[編集]

Shadow DOM(シャドウDOM)は、Web Componentsを構成する主要な技術の1つであり、DOMツリーをカプセル化して外部から影響を受けないようにする仕組みを提供します。これにより、カスタム要素(Custom Elements)や再利用可能なコンポーネントの作成が容易になり、CSSやJavaScriptのスコープを分離することで、他の要素との干渉を防ぐことができます。

この章では、Shadow DOMの基本概念、使用例、スタイルのスコープ、イベントの挙動、メリットと制約について解説します。

基本概念

[編集]

Shadow DOMは、通常のDOMツリーとは別に「シャドウツリー」を作成することで動作します。このシャドウツリーは、ホスト要素(shadow host)にアタッチされ、外部のDOMツリーやCSSスタイルから隔離されます。

基本的な構造は以下のようになります。

<host-element>
    #shadow-root (open)
        <style>
            p {
                color: red;
            }
        </style>
        <p>これはShadow DOM内のコンテンツです。</p>
</host-element>

この例では、<host-element>がShadow DOMをホストする要素であり、その内部の#shadow-rootにシャドウツリーが作成されています。

Shadow DOMの作成方法

[編集]

Shadow DOMはJavaScriptを使用してプログラム的に作成されます。以下に基本的な作成方法を示します。

Shadow DOMの作成

[編集]
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Shadow DOMの基本例</title>
</head>
<body>
    <div id="host"></div>

    <script>
        // Shadow DOMの作成
        const host = document.getElementById('host');
        const shadowRoot = host.attachShadow({ mode: 'open' });

        // Shadow DOMに内容を追加
        shadowRoot.innerHTML = `
            <style>
                p {
                    color: blue;
                    font-weight: bold;
                }
            </style>
            <p>これはShadow DOM内のテキストです。</p>
        `;
    </script>
</body>
</html>

このコードでは、attachShadowメソッドを使用して、ホスト要素(<div id="host">)にシャドウルートを作成しています。

  • mode属性: Shadow DOMのアクセスモードを指定します。
    • open: JavaScriptからシャドウルートにアクセス可能。
    • closed: JavaScriptからシャドウルートにアクセス不可。

Shadow DOMのスタイリング

[編集]

Shadow DOMは、スタイルスコープがカプセル化されているため、外部のCSSや親要素のスタイルの影響を受けません。また、Shadow DOM内のスタイルも外部には影響を与えません。

スタイルの分離

[編集]
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Shadow DOMのスタイル</title>
    <style>
        /* 外部スタイル */
        p {
            color: green;
        }
    </style>
</head>
<body>
    <div id="host"></div>

    <script>
        const host = document.getElementById('host');
        const shadowRoot = host.attachShadow({ mode: 'open' });

        shadowRoot.innerHTML = `
            <style>
                p {
                    color: red;
                }
            </style>
            <p>Shadow DOM内のスタイルが適用されます。</p>
        `;

        // 外部のDOM
        const outsideP = document.createElement('p');
        outsideP.textContent = '外部DOMのスタイルが適用されます。';
        document.body.appendChild(outsideP);
    </script>
</body>
</html>

この例では、外部のp要素に緑色が適用される一方、Shadow DOM内のp要素には赤色が適用されます。

Shadow DOMとイベント

[編集]

Shadow DOMでは、イベントの伝播においてもカプセル化が適用されます。具体的には、シャドウツリー内で発生したイベントは、ホスト要素を越えて外部には影響を与えません。

イベントの挙動

[編集]
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Shadow DOMのイベント</title>
</head>
<body>
    <div id="host"></div>

    <script>
        const host = document.getElementById('host');
        const shadowRoot = host.attachShadow({ mode: 'open' });

        shadowRoot.innerHTML = `
            <button id="shadowButton">Shadow DOMのボタン</button>
        `;

        // Shadow DOM内のイベント
        shadowRoot.getElementById('shadowButton').addEventListener('click', () => {
            console.log('Shadow DOM内のボタンがクリックされました');
        });

        // 外部のイベント
        host.addEventListener('click', () => {
            console.log('ホスト要素がクリックされました');
        });
    </script>
</body>
</html>

この例では、Shadow DOM内のボタンをクリックすると、シャドウツリー内でイベントが処理され、外部には伝播しません。

Shadow DOMのメリット

[編集]
  1. スタイルとスクリプトの分離: カプセル化により、他のコンポーネントや外部要素との干渉を防ぎます。
  2. 再利用性の向上: モジュール化されたコンポーネントを容易に作成できます。
  3. セキュリティの向上: シャドウツリー内の内容が外部から見えないようにすることで、セキュリティが向上します。

制約と注意点

[編集]
  1. ブラウザのサポート: ほとんどのモダンブラウザでサポートされていますが、古いブラウザでは使用できません。
  2. デバッグの難しさ: 開発ツールでシャドウツリーを見るには、特定の操作が必要です。
  3. パフォーマンス: 複数のShadow DOMを持つ要素が増えると、DOM操作のコストが上がる可能性があります。

Shadow DOMは、モダンなWeb開発における重要なツールであり、スコープ分離と再利用性を提供することで、堅牢なコンポーネント設計を可能にします。この章で学んだ基礎を活用し、カスタム要素の開発に役立ててください。