צללית DOM ב-TypeScript

צללית DOM ב-TypeScript

מאמר זה מסביר את צללית ה-DOM ב-TypeScript.

נסביר בפירוט את כל מה שצריך לדעת מהבסיס של Shadow DOM ועד לשימוש המתקדם, ונספק קוד לדוגמה להתנסות מעשית.

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>

הסבר מפורט ומדריך מעשי שלב אחר שלב על צללית DOM

צללית DOM היא אחת מהרכיבים המרכזיים של רכיבי הרשת. היא יוצרת עץ DOM מבודד שמפריד בין הסגנון והמבנה של הרכיב לבין החוץ. כאן נספק הסבר מפורט על היסודות של צללית DOM, עד למקרי שימוש מעשיים, יחד עם קוד דוגמה מעשי.

מהי צללית DOM?

Shadow DOM היא טכנולוגיית תקן אינטרנטית עם המאפיינים הבאים.

  1. כימוס

    צללית DOM מפרידה בין מבנה ה-DOM הפנימי של רכיב לבין החוץ. סגנונות וסקריפטים אחרים אינם מפריעים, ומשפרים את יכולת השימוש החוזר.

  2. תחום סגנונות עצמאי

    סגנונות בתוך צללית DOM אינם משפיעים על CSS חיצוני. באופן דומה, סגנונות חיצוניים אינם חלים בתוך צללית DOM.

  3. עץ DOM מבודד

    צללית DOM קיימת כעץ נפרד מה-DOM הרגיל, עם גישה מוגבלת מה-DOM האב.

שימוש בסיסי ב-צללית DOM

הקוד הבא הוא הדוגמה הראשונה לשימוש ב-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`;
  • הדפדפן יציג את הטקסט הכחול: 'זה בתוך Shadow DOM!'. הסגנון של טקסט זה אינו מושפע מ-CSS חיצוני.

שלבים בסיסיים של Shadow DOM

כדי להשתמש ב־Shadow DOM, כפי שמוצג בקוד הזה, עליך להשתמש בפונקציה attachShadow ב־JavaScript. להלן השלבים הבסיסיים:.

  1. יצירת רכיבים מותאמים אישית אלמנט מותאם אישית הוא תג שאתה יוצר בעצמך בנוסף לתגיות ה־HTML הסטנדרטיות. בשלב הזה תיצור מחלקה שיורשת מ־HTMLElement, כמו מחלקת MyElement, וכך הדפדפן יזהה אותה כתג חדש. כדי שתוכל להשתמש במחלקה החדשה כתג מותאם אישית ב־HTML, עליך לרשום אותה באמצעות customElements.define().

  2. צירוף צללית DOM על ידי קריאה ל־this.attachShadow() בתוך האלמנט המותאם אישית, תוכל ליצור Shadow DOM.

  3. הוספת HTML ו-CSS בתוך צללית DOM בתוך ה־Shadow DOM תוכל להגדיר מבנה HTML וסגנונות משלך. לדוגמה, על ידי הגדרת HTML ו־CSS דרך innerHTML תוכל להקנות לו מראה והתנהגות עצמאיים שאינם מושפעים מ־CSS או HTML חיצוניים. באופן זה תוכל ליצור רכיבים מבודדים (מואפסים).

מצבי Shadow DOM: פתוח ו-סגור

ל-Shadow DOM יש שני מצבים: פתוח ו-סגור.

  • מצב פתוח: ניתן לגשת ל-shadowRoot המחובר ל-Shadow DOM מבחוץ.
  • מצב סגור: לא ניתן לגשת ל-shadowRoot המחובר ל-Shadow DOM מבחוץ.

להלן דוגמת קוד שמראה את ההבדלים בין שני המצבים.

 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が出力される
  • בחירת מצב סגור הופכת את מאפיין ה-shadowRoot לבלתי נגיש.

הכלת סגנונות באמצעות Shadow DOM

באמצעות Shadow DOM, ניתן להכיל סגנונות לחלוטין בתוך הרכיבים שלך.

הדוגמה הבאה מדגימה את ההפרדה בין סגנונות גלובליים לסגנונות בתוך ה-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בתוךShadow DOM` אינם מושפעים מתבניות גלובליות ויש להם סגנונות ייחודיים משלהם.

דוגמה מעשית ל-Shadow DOM: טיפ מותאם אישית

בהמשך, נציג דוגמה ליצירת טיפ מותאם אישית באמצעות 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`;
  • קוד זה יוצר טיפ מותאם אישית ומציג אותו עם עיצוב בעת ריחוף.

סיכום

Shadow DOM הוא טכנולוגיה חשובה עבור רכיבי אינטרנט, ומספק DOM מוכלל והיקף סגנונות. כאן סקרנו את היסודות של Shadow DOM, השימוש בו, ההבדלים בין המצבים, הכלת סגנונות ודוגמאות מעשיות. באמצעות אלו תוכל לבנות רכיבים חוזרים ושימושיים במיוחד.

תוכלו לעקוב אחר המאמר שלמעלה באמצעות Visual Studio Code בערוץ היוטיוב שלנו. נא לבדוק גם את ערוץ היוטיוב.

YouTube Video