Shadow DOM dalam JavaScript
Artikel ini menerangkan tentang Shadow DOM dalam JavaScript.
YouTube Video
javascript-html-shadow-dom.html
1<!DOCTYPE html>
2<html lang="en">
3<head>
4 <meta charset="UTF-8">
5 <title>JavaScript & 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 id="shadow-host">Shadow Root Element</div>
90 <my-card></my-card>
91 </div>
92
93 <div class="container">
94 <h1>JavaScript Console</h1>
95 <button id="executeBtn">Execute</button>
96 <div id="output"></div>
97 </div>
98
99 <div>
100 <h2>Slot Sample</h2>
101 <my-element>
102 <h3 slot="header">Header Content</h1>
103 <p slot="content">Main Content</p>
104 </my-element>
105 </div>
106
107 <script>
108 // Override console.log to display messages in the #output element
109 (function () {
110 const originalLog = console.log;
111 console.log = function (...args) {
112 originalLog.apply(console, args);
113 const output = document.getElementById('output');
114 output.textContent += args.map(String).join(' ') + '\n';
115 };
116 })();
117
118 document.getElementById('executeBtn').addEventListener('click', () => {
119 // Prevent multiple loads
120 if (document.getElementById('externalScript')) return;
121
122 const script = document.createElement('script');
123 script.src = 'javascript-html-shadow-dom.js';
124 script.id = 'externalScript';
125 //script.onload = () => console.log('javascript-html-shadow-dom.js loaded and executed.');
126 //script.onerror = () => console.log('Failed to load javascript-html-shadow-dom.js.');
127 document.body.appendChild(script);
128 });
129 </script>
130</body>
131</html>
Memahami Shadow DOM
Shadow DOM
adalah ciri yang kuat dalam piawaian Komponen Web yang membolehkan pengkapsulan gaya dan struktur DOM dalam komponen. Ciri ini menghalang gangguan gaya dan skrip antara komponen dan dokumen utama.
Shadow DOM
dalam JavaScript
Shadow DOM
menyediakan cara untuk mencipta pokok DOM yang terhad yang dikaitkan dengan elemen DOM biasa. Pokok bayangan ini diasingkan daripada dokumen keseluruhan, di mana gaya dan skrip luaran tidak mempengaruhinya, dan gaya serta skrip dalaman tidak tersebar keluar.
Sebagai contoh, jika anda mencipta komponen butang tersuai menggunakan Shadow DOM
, gayanya tidak akan mengganggu elemen lain di halaman itu. Begitu juga, elemen dengan nama kelas yang sama tidak akan bertembung.
Kandungan HTML biasa di luar Shadow DOM
dirujuk sebagai Light DOM
.
Manfaat Shadow DOM
-
Pengkapsulan
Shadow DOM
memisahkan gaya dan fungsi, mengelakkan konflik dengan gaya dan skrip global.
-
Boleh Digunakan Semula
- Komponen yang dibina dengan
Shadow DOM
boleh digunakan semula dalam pelbagai projek tanpa risau tentang konflik gaya.
- Komponen yang dibina dengan
-
Penyelenggaraan
- Pengkapsulan menjadikan logik dan gaya komponen berdikari, memudahkan penyahpepijatan dan penyelenggaraan.
Membuat Shadow DOM
Untuk menggunakan Shadow DOM
, anda perlu melampirkan akar bayangan kepada elemen HTML. Berikut ialah contoh ringkas:.
1// Select the host element
2const hostElement = document.querySelector('#shadow-host');
3
4// Attach a shadow root
5const shadowRoot = hostElement.attachShadow({ mode: 'open' });
Penjelasan
Kod ini merangkumi elemen-elemen berikut:.
-
Elemen Hos
- Elemen DOM biasa yang dilekatkan shadow root (dalam kes ini,
#shadow-host
).
- Elemen DOM biasa yang dilekatkan shadow root (dalam kes ini,
-
Akar Shadow
- Akar bagi pohon shadow yang dicipta menggunakan
attachShadow
.
- Akar bagi pohon shadow yang dicipta menggunakan
-
Mod
- Dalam mod
open
, JavaScript luar boleh mengakses shadow root melaluielement.shadowRoot
. Sebaliknya, modclosed
tidak membenarkan akses.
- Dalam mod
Penggayaan dalam Shadow DOM
Shadow DOM
mempunyai skop gaya tersendiri. Gaya yang ditentukan dalam shadow tree hanya terpakai pada elemen dalam pokok tersebut. Berikut adalah contohnya:.
1// Add content to the shadow root
2shadowRoot.innerHTML = `
3 <style>
4 p {
5 color: green;
6 }
7 </style>
8 <p>Scoped style inside Shadow DOM.</p>
9`;
Walaupun terdapat gaya yang bercanggah dalam dokumen utama, ia tidak menjejaskan perenggan di dalam pohon shadow.
1const content = document.getElementById('content');
2content.innerHTML = `
3 <style>
4 p {
5 color: red;
6 }
7 </style>
8 <p>This is in the main DOM.</p>
9`;
- Perenggan di dalam
Shadow DOM
kekal berwarna hijau, manakala yang di luar berwarna merah.
Acara dalam Shadow DOM
Acara dalam Shadow DOM
adalah serupa dengan acara DOM biasa tetapi mungkin berkelakuan berbeza dari segi penyebaran kerana enkapsulasi.
Berikut adalah contohnya:.
1// Add an event listener inside Shadow DOM
2shadowRoot.innerHTML = `
3 <div id="button-container">
4 <button id="shadow-button">Click Me</button>
5 </div>
6`;
7
8shadowRoot.querySelector('#shadow-button').addEventListener('click', (event) => {
9 console.log('Button : Button clicked inside Shadow DOM');
10 console.log(event.target);
11});
12
13shadowRoot.querySelector('#button-container').addEventListener('click', (event) => {
14 console.log('Container : Button clicked inside Shadow DOM');
15 console.log(event.target);
16});
17
18hostElement.addEventListener('click', (event) => {
19 console.log('Event bubbled to the host element');
20 console.log(event.target);
21});
22
23document.addEventListener('click', (event) => {
24 console.log('Document listener');
25 console.log(event.target);
26});
- Apabila butang ditekan, kedua-dua pendengar diaktifkan, menunjukkan tingkah laku gelembung acara.
- Apabila satu acara yang berasal dari dalam
Shadow DOM
naik keLight DOM
,target
acara tersebut akan ditulis semula kepada elemen hos dan bukannya sumber asal.- Dalam contoh ini,
event.target
di dalamShadow DOM
adalah elemenbutton
sebenar, tetapi di luarShadow DOM
, ia digantikan dengan elemen hosdiv
.
- Dalam contoh ini,
Shadow DOM
dan Elemen Tersuai
Shadow DOM
dan elemen tersuai adalah komponen utama dalam Web Components
. Ia adalah teknologi yang digunakan untuk mencipta komponen UI yang boleh diguna semula dan terenkapsulasi.
1class MyCard extends HTMLElement {
2 constructor() {
3 super();
4 const shadow = this.attachShadow({ mode: 'open' });
5 shadow.innerHTML = `
6 <style>
7 p {
8 color: blue;
9 }
10 </style>
11 <p>I'm inside shadow DOM</p>
12 `;
13 }
14}
15
16customElements.define('my-card', MyCard);
Dokumen utama mengandungi HTML seperti berikut:.
1<my-card></my-card>
- Dengan menggunakan
Shadow DOM
di dalam elemen tersuai, anda boleh membina komponen yang boleh diguna semula dan tahan terhadap konflik gaya. Dalam kod ini, satu tag bernamamy-card
dicipta dan dihubungkan dengan kelasMyCard
. Elemen<p>
di dalammy-card
tidak terpengaruh oleh gaya luar dan sentiasa dipaparkan dalam warna biru.
Slot: Mengagihkan Kandungan Light DOM
Slot membolehkan anda memproyeksikan kandungan Light DOM
ke dalam Shadow DOM
. Berikut adalah contohnya:.
1class MyElement extends HTMLElement {
2 constructor() {
3 super();
4 const shadow = this.attachShadow({ mode: 'open' });
5
6 shadow.innerHTML = `
7 <style>
8 .container {
9 border: 2px solid #ccc;
10 padding: 16px;
11 border-radius: 8px;
12 font-family: sans-serif;
13 }
14 .header {
15 font-size: 1.2em;
16 color: darkblue;
17 margin-bottom: 8px;
18 }
19 .content {
20 font-size: 1em;
21 color: #333;
22 }
23 </style>
24 <div class="container">
25 <div class="header">
26 <slot name="header"></slot>
27 </div>
28 <div class="content">
29 <slot name="content"></slot>
30 </div>
31 </div>
32 `;
33 }
34}
35
36customElements.define('my-element', MyElement);
Dokumen utama mengandungi HTML seperti berikut:.
1<my-element>
2 <h3 slot="header">Header Content</h1>
3 <p slot="content">Main Content</p>
4</my-element>
- Elemen
slot
di dalamShadow DOM
memaparkan kandunganLight DOM
yang mempunyai atributslot
yang sepadan.
Kesimpulan
Shadow DOM
adalah alat penting untuk membina komponen web yang kukuh, boleh digunakan semula, dan mudah diselenggara. Dengan mengenkapsulasi gaya dan fungsi, ia mengurangkan potensi konflik dan mempermudah pengurusan kod asas.
Anda boleh mengikuti artikel di atas menggunakan Visual Studio Code di saluran YouTube kami. Sila lihat juga saluran YouTube kami.