Shadow DOM dans TypeScript

Shadow DOM dans TypeScript

Cet article explique le Shadow DOM dans TypeScript.

Nous expliquerons en détail tout, des bases du Shadow DOM à son utilisation pratique, et fournirons des exemples de code à manipuler.

YouTube Video

typescript-html-shadow-dom.html
  1<!DOCTYPE html>
  2<html lang="en">
  3<head>
  4  <meta charset="UTF-8">
  5  <title>TypeScript &amp; HTML</title>
  6  <style>
  7    * {
  8        box-sizing: border-box;
  9    }
 10
 11    body {
 12        margin: 0;
 13        padding: 1em;
 14        padding-bottom: 10em;
 15        font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
 16        background-color: #f7f9fc;
 17        color: #333;
 18        line-height: 1.6;
 19    }
 20
 21    .container {
 22        max-width: 800px;
 23        margin: 0 auto;
 24        padding: 1em;
 25        background-color: #ffffff;
 26        border: 1px solid #ccc;
 27        border-radius: 10px;
 28        box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
 29    }
 30
 31    h1, h2 {
 32        font-size: 1.2rem;
 33        color: #007bff;
 34        margin-top: 0.5em;
 35        margin-bottom: 0.5em;
 36        border-left: 5px solid #007bff;
 37        padding-left: 0.6em;
 38        background-color: #e9f2ff;
 39    }
 40
 41    button {
 42        display: block;
 43        margin: 1em auto;
 44        padding: 0.75em 1.5em;
 45        font-size: 1rem;
 46        background-color: #007bff;
 47        color: white;
 48        border: none;
 49        border-radius: 6px;
 50        cursor: pointer;
 51        transition: background-color 0.3s ease;
 52    }
 53
 54    button:hover {
 55        background-color: #0056b3;
 56    }
 57
 58    #output {
 59        margin-top: 1em;
 60        background-color: #1e1e1e;
 61        color: #0f0;
 62        padding: 1em;
 63        border-radius: 8px;
 64        min-height: 200px;
 65        font-family: Consolas, monospace;
 66        font-size: 0.95rem;
 67        overflow-y: auto;
 68        white-space: pre-wrap;
 69    }
 70
 71    .highlight {
 72        outline: 3px solid #ffc107; /* yellow border */
 73        background-color: #fff8e1;  /* soft yellow background */
 74        transition: background-color 0.3s ease, outline 0.3s ease;
 75    }
 76
 77    .active {
 78        background-color: #28a745; /* green background */
 79        color: #fff;
 80        box-shadow: 0 0 10px rgba(40, 167, 69, 0.5);
 81        transition: background-color 0.3s ease, box-shadow 0.3s ease;
 82    }
 83  </style>
 84</head>
 85<body>
 86    <div class="container">
 87        <h2>HTML Sample</h2>
 88        <div id="content"></div>
 89    </div>
 90
 91    <div class="container">
 92        <h1>JavaScript Console</h1>
 93        <button id="executeBtn">Execute</button>
 94        <div id="output"></div>
 95    </div>
 96
 97    <script>
 98        // Override console.log to display messages in the #output element
 99        (function () {
100            const originalLog = console.log;
101            console.log = function (...args) {
102                originalLog.apply(console, args);
103                const output = document.getElementById('output');
104                output.textContent += args.map(String).join(' ') + '\n';
105            };
106        })();
107
108        document.getElementById('executeBtn').addEventListener('click', () => {
109            // Prevent multiple loads
110            if (document.getElementById('externalScript')) return;
111
112            const script = document.createElement('script');
113            script.src = '/out/main.js';
114            script.id = 'externalScript';
115            //script.onload = () => console.log('typescript-html-shadow-dom.js loaded and executed.');
116            //script.onerror = () => console.log('Failed to load typescript-html-shadow-dom.js.');
117            document.body.appendChild(script);
118        });
119    </script>
120</body>
121</html>

Explication détaillée et guide pratique étape par étape du Shadow DOM

Le Shadow DOM est l'un des éléments clés des composants Web. Il crée un arbre DOM encapsulé qui sépare le style et la structure du composant de l'extérieur. Ici, nous fournirons une explication détaillée des bases du Shadow DOM ainsi que de ses cas d'utilisation pratiques, accompagnée de code d'exemple pratique.

Qu'est-ce que le Shadow DOM ?

Shadow DOM est une technologie standard du web avec les caractéristiques suivantes.

  1. Encapsulation

    Le Shadow DOM sépare la structure DOM interne d'un composant de l'extérieur. Les autres styles et scripts n'interfèrent pas, améliorant ainsi la réutilisabilité.

  2. Portée de style indépendante

    Les styles à l'intérieur du Shadow DOM n'affectent pas les CSS externes. De même, les styles externes ne s'appliquent pas à l'intérieur du Shadow DOM.

  3. Arbre DOM isolé

    Le Shadow DOM existe comme un arbre distinct du DOM régulier, avec un accès restreint depuis le DOM parent.

Utilisation de base du Shadow DOM

Le code suivant est le premier exemple utilisant le Shadow DOM.

 1class MyElement extends HTMLElement {
 2  constructor() {
 3    super();
 4
 5    // Attach Shadow DOM
 6    const shadowRoot = this.attachShadow({ mode: 'open' });
 7
 8    // Add HTML and CSS inside Shadow DOM
 9    shadowRoot.innerHTML = `
10      <style>
11        p {
12          color: blue;
13          font-size: 18px;
14        }
15      </style>
16      <p>This is inside Shadow DOM!</p>
17    `;
18  }
19}
20
21// Register the custom element
22customElements.define('my-element', MyElement);
23
24document.getElementById('content').innerHTML = `
25  <my-element></my-element>
26`;
  • Le navigateur affichera le texte en bleu : 'Ceci est à l'intérieur du Shadow DOM !'. Le style de ce texte n'est pas affecté par le CSS externe.

Étapes de base du Shadow DOM

Pour utiliser le Shadow DOM, comme le montre ce code, vous utilisez la méthode attachShadow en JavaScript. Voici les étapes de base :.

  1. Créer des éléments personnalisés Un élément personnalisé est une balise définie par l'utilisateur que vous pouvez créer en plus des balises HTML standard. À cette étape, vous créez une classe qui étend HTMLElement, comme la classe MyElement, afin que le navigateur la reconnaisse comme une nouvelle balise. En enregistrant la classe créée avec customElements.define(), vous pourrez l'utiliser comme une balise personnalisée dans le HTML.

  2. Attacher le Shadow DOM En exécutant this.attachShadow() à l'intérieur d'un élément personnalisé, vous pouvez créer un Shadow DOM.

  3. Ajouter du HTML et du CSS à l'intérieur du Shadow DOM Dans le Shadow DOM, vous pouvez définir votre propre structure HTML et vos styles. Par exemple, en affectant du HTML et du CSS à innerHTML, vous pouvez lui donner une apparence et un comportement indépendants, sans être affecté par le CSS ou le HTML externes. Cela vous permet de créer des composants encapsulés.

Modes du Shadow DOM : open et closed

Le Shadow DOM a deux modes : open et closed.

  • Mode ouvert : Le shadowRoot attaché au Shadow DOM peut être accédé de l'extérieur.
  • Mode fermé : Le shadowRoot attaché au Shadow DOM ne peut pas être accédé de l'extérieur.

Ci-dessous se trouve un exemple de code qui montre les différences entre les deux modes.

 1class OpenElement extends HTMLElement {
 2  constructor() {
 3    super();
 4    this.attachShadow({ mode: 'open' }).innerHTML = `
 5      <p>Open Shadow DOM</p>
 6    `;
 7  }
 8}
 9
10class ClosedElement extends HTMLElement {
11  constructor() {
12    super();
13    this.attachShadow({ mode: 'closed' }).innerHTML = `
14      <p>Closed Shadow DOM</p>
15    `;
16  }
17}
18
19customElements.define('open-element', OpenElement);
20customElements.define('closed-element', ClosedElement);
21
22document.getElementById('content').innerHTML = `
23  <open-element></open-element>
24  <closed-element></closed-element>
25`;
26
27const openElement = document.querySelector('open-element') as OpenElement;
28console.log(openElement.shadowRoot); // ShadowRootが出力される
29
30const closedElement = document.querySelector('closed-element') as ClosedElement;
31console.log(closedElement.shadowRoot); // nullが出力される
  • Choisir le mode closed rend la propriété shadowRoot inaccessible.

Encapsulation du style avec le Shadow DOM

Avec le Shadow DOM, vous pouvez complètement encapsuler les styles dans vos composants.

L'exemple suivant démontre la séparation entre les styles globaux et les styles au sein du Shadow DOM.

 1class StyledElement extends HTMLElement {
 2  constructor() {
 3    super();
 4    const shadowRoot = this.attachShadow({ mode: 'open' });
 5
 6    shadowRoot.innerHTML = `
 7      <style>
 8        p {
 9          background-color: lightblue;
10          padding: 10px;
11          border: 1px solid blue;
12        }
13      </style>
14      <p>Shadow DOM Styled Content</p>
15    `;
16  }
17}
18
19customElements.define('styled-element', StyledElement);
20
21document.getElementById('content').innerHTML = `
22  <style>
23    p {
24      color: red;
25      font-weight: bold;
26    }
27  </style>
28
29  <styled-element></styled-element>
30`;
  • p à l’intérieur du Shadow DOM ne sont pas affectés par les styles globaux et ont leurs propres styles uniques appliqués.

Exemple pratique de Shadow DOM : Info-bulle personnalisée

Ensuite, nous présentons un exemple de création d'une info-bulle personnalisée avec le Shadow DOM.

 1class Tooltip extends HTMLElement {
 2  constructor() {
 3    super();
 4
 5    const shadowRoot = this.attachShadow({ mode: 'open' });
 6
 7    shadowRoot.innerHTML = `
 8      <style>
 9        :host {
10          position: relative;
11          display: inline-block;
12          cursor: pointer;
13        }
14
15        .tooltip {
16          visibility: hidden;
17          background-color: black;
18          color: white;
19          text-align: center;
20          padding: 5px;
21          border-radius: 5px;
22          position: absolute;
23          bottom: 125%;
24          left: 50%;
25          transform: translateX(-50%);
26          white-space: nowrap;
27        }
28
29        :host(:hover) .tooltip {
30          visibility: visible;
31        }
32      </style>
33      <slot></slot>
34      <div class="tooltip">Tooltip text</div>
35    `;
36  }
37}
38
39customElements.define('custom-tooltip', Tooltip);
40
41document.getElementById('content').innerHTML = `
42  <custom-tooltip>
43    Hover over me
44    <span slot="tooltip">This is a custom tooltip!</span>
45  </custom-tooltip>
46`;
  • Ce code crée une info-bulle personnalisée et affiche une info-bulle stylisée au survol.

Résumé

Le Shadow DOM est une technologie essentielle pour les Web Components, offrant un DOM encapsulé et une portée de style. Ici, nous avons couvert les bases du Shadow DOM, son utilisation, les différences de mode, l'encapsulation des styles et des exemples pratiques. En tirant parti de ces éléments, vous pouvez construire des composants réutilisables et robustes.

Vous pouvez suivre l'article ci-dessus avec Visual Studio Code sur notre chaîne YouTube. Veuillez également consulter la chaîne YouTube.

YouTube Video