コンテンツにスキップ

HTML/Custom Element

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

Custom Element

[編集]

Custom Element(カスタム要素)は、Web Componentsの中核を成す技術であり、HTMLに新しいタグを作成できる仕組みを提供します。これにより、再利用可能で独自の振る舞いや見た目を持つ要素を定義でき、Webアプリケーションのモジュール化が容易になります。

この章では、Custom Elementの基本的な構文、登録方法、ライフサイクルコールバック、属性の操作、そして実践的な例を通じてその使い方を解説します。

基本概念

[編集]

Custom Elementは、classキーワードを使用して作成されるES6クラスをベースに定義されます。このクラスは、HTMLElementを継承し、要素の振る舞いをカスタマイズします。

以下は、簡単なカスタム要素の例です。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>Custom Elementの基本例</title>
</head>
<body>
    <hello-world></hello-world>

    <script>
        class HelloWorld extends HTMLElement {
            constructor() {
                super();
                this.innerHTML = '<p>こんにちは、世界!</p>';
            }
        }

        // カスタム要素を登録
        customElements.define('hello-world', HelloWorld);
    </script>
</body>
</html>

この例では、HelloWorldというクラスが定義され、<hello-world>タグとして登録されています。

カスタム要素の登録

[編集]

カスタム要素を利用するには、customElements.define()メソッドでタグ名とクラスを登録します。

登録方法

[編集]
// タグ名は必ずハイフンを含む必要があります
customElements.define('my-element', MyElement);
  • customElements.defineメソッド:
    • 第1引数: タグ名(例: 'my-element'
    • 第2引数: クラス(例: MyElement
    • 第3引数(オプション): オプション(拡張要素用)

タグ名にハイフンを含めることで、カスタム要素とネイティブ要素の名前空間が衝突しないようにしています。

ライフサイクルコールバック

[編集]

Custom Elementには、要素のライフサイクルに応じて呼び出されるコールバックメソッドが用意されています。これらを活用することで、初期化やクリーンアップ処理を実装できます。

主なライフサイクルコールバック

[編集]
  1. connectedCallback: 要素がDOMに追加されたときに呼び出されます。
  2. disconnectedCallback: 要素がDOMから削除されたときに呼び出されます。
  3. attributeChangedCallback: 監視対象の属性が変更されたときに呼び出されます。
  4. adoptedCallback: 要素が別のドキュメントに移動されたときに呼び出されます。

使用例

[編集]
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>ライフサイクルコールバックの例</title>
</head>
<body>
    <custom-timer></custom-timer>

    <script>
        class CustomTimer extends HTMLElement {
            constructor() {
                super();
                this.startTime = null;
            }

            connectedCallback() {
                this.startTime = Date.now();
                this.innerHTML = '<p>タイマーが開始されました。</p>';
                console.log('Timer started.');
            }

            disconnectedCallback() {
                const elapsedTime = Date.now() - this.startTime;
                console.log(`Timer stopped. 経過時間: ${elapsedTime}ms`);
            }
        }

        customElements.define('custom-timer', CustomTimer);

        // 要素の動的追加と削除
        setTimeout(() => {
            const timer = document.createElement('custom-timer');
            document.body.appendChild(timer);

            setTimeout(() => {
                document.body.removeChild(timer);
            }, 2000);
        }, 1000);
    </script>
</body>
</html>

この例では、タイマー開始時と終了時にメッセージがログに記録されます。

属性の操作

[編集]

Custom Elementでは、標準のHTML属性を扱うことができ、attributeChangedCallbackを使用して属性変更時の処理を実装できます。

属性の監視

[編集]

監視対象の属性を定義するには、静的メソッドobservedAttributesを使用します。

class MyElement extends HTMLElement {
    static get observedAttributes() {
        return ['color', 'size'];
    }

    attributeChangedCallback(name, oldValue, newValue) {
        console.log(`${name}属性が変更されました: ${oldValue}${newValue}`);
    }
}

使用例

[編集]
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>属性の監視</title>
</head>
<body>
    <custom-box color="red"></custom-box>

    <script>
        class CustomBox extends HTMLElement {
            static get observedAttributes() {
                return ['color'];
            }

            attributeChangedCallback(name, oldValue, newValue) {
                if (name === 'color') {
                    this.style.backgroundColor = newValue;
                }
            }
        }

        customElements.define('custom-box', CustomBox);

        // 属性の変更
        setTimeout(() => {
            const box = document.querySelector('custom-box');
            box.setAttribute('color', 'blue');
        }, 2000);
    </script>
</body>
</html>

この例では、color属性が変更されると、背景色が動的に更新されます。

実践例: カスタムカード要素

[編集]

以下は、カスタムカード要素の例です。カード要素にはタイトルとコンテンツが含まれ、Shadow DOMを使用してスタイリングがカプセル化されています。

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>カスタムカード要素</title>
</head>
<body>
    <custom-card title="カードのタイトル">
        <p>これはカードのコンテンツです。</p>
    </custom-card>

    <script>
        class CustomCard extends HTMLElement {
            constructor() {
                super();
                const shadowRoot = this.attachShadow({ mode: 'open' });
                shadowRoot.innerHTML = `
                    <style>
                        .card {
                            border: 1px solid #ccc;
                            padding: 16px;
                            border-radius: 8px;
                            box-shadow: 2px 2px 8px rgba(0, 0, 0, 0.1);
                        }
                        .title {
                            font-size: 1.25em;
                            margin-bottom: 8px;
                        }
                    </style>
                    <div class="card">
                        <div class="title">${this.getAttribute('title')}</div>
                        <slot></slot>
                    </div>
                `;
            }
        }

        customElements.define('custom-card', CustomCard);
    </script>
</body>
</html>

このカスタム要素は、再利用可能なカード要素を簡単に作成するためのテンプレートとして利用できます。

Custom Elementは、モダンなWeb開発において非常に強力なツールであり、再利用可能なコンポーネントの構築を可能にします。この章を通じて、カスタム要素の基本から応用までを理解し、自分だけの独自要素を作成してみましょう。