Shadow DOM dalam JavaScript
Artikel ini menjelaskan 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 fitur kuat dari standar Web Components yang memungkinkan enkapsulasi gaya dan struktur DOM di dalam komponen. Fitur ini mencegah gangguan dari gaya dan skrip antara komponen dan dokumen utama.
Shadow DOM dalam JavaScript
Shadow DOM menyediakan cara untuk membuat pohon DOM yang dibatasi terkait dengan elemen DOM biasa. Pohon bayangan ini terisolasi dari keseluruhan dokumen, di mana gaya dan skrip eksternal tidak mempengaruhinya, serta gaya dan skrip internalnya tidak bocor keluar.
Sebagai contoh, jika Anda membuat komponen tombol kustom menggunakan Shadow DOM, gaya-gayanya tidak akan mengganggu elemen lain di halaman. Demikian pula, elemen dengan nama kelas yang sama tidak akan konflik.
Konten HTML biasa yang berada di luar Shadow DOM disebut sebagai Light DOM.
Manfaat Shadow DOM
-
Enkapsulasi
Shadow DOMmemisahkan gaya dan fungsi, sehingga mencegah konflik dengan gaya dan skrip global.
-
Dapat digunakan kembali
- Komponen yang dibangun dengan
Shadow DOMdapat digunakan kembali di berbagai proyek tanpa khawatir terjadi konflik gaya.
- Komponen yang dibangun dengan
-
Mudah dipelihara
- Enkapsulasi membuat logika dan gaya komponen menjadi terpisah, sehingga debugging dan pemeliharaan menjadi lebih mudah.
Membuat Shadow DOM
Untuk menggunakan Shadow DOM, Anda perlu melampirkan shadow root ke elemen HTML. Berikut adalah contoh sederhana:.
1// Select the host element
2const hostElement = document.querySelector('#shadow-host');
3
4// Attach a shadow root
5const shadowRoot = hostElement.attachShadow({ mode: 'open' });Penjelasan
Kode ini mencakup elemen-elemen berikut:.
-
Elemen Host
- Sebuah elemen DOM biasa yang menjadi tempat menempelkan shadow root (dalam hal ini,
#shadow-host).
- Sebuah elemen DOM biasa yang menjadi tempat menempelkan shadow root (dalam hal ini,
-
Shadow Root
- Root dari pohon shadow yang dibuat menggunakan
attachShadow.
- Root dari pohon shadow yang dibuat menggunakan
-
Mode
- Dalam mode
open, JavaScript eksternal dapat mengakses shadow root melaluielement.shadowRoot. Di sisi lain, modeclosedtidak mengizinkan akses.
- Dalam mode
Pemformatan dalam Shadow DOM
Shadow DOM memiliki lingkup gaya sendiri. Gaya yang ditentukan dalam pohon shadow hanya berlaku untuk elemen-elemen dalam pohon 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`;Meskipun terdapat konflik gaya pada dokumen utama, paragraf di dalam pohon shadow tidak akan terpengaruh.
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`;- Paragraf di dalam
Shadow DOMtetap berwarna hijau, sedangkan yang di luar berwarna merah.
Event di dalam Shadow DOM
Event di dalam Shadow DOM mirip dengan event DOM biasa tetapi dapat berperilaku berbeda dalam hal propagasi karena 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});- Ketika tombol diklik, kedua listener terpicu, menunjukkan perilaku bubbling event.
- Ketika sebuah event yang berasal dari dalam
Shadow DOMnaik keLight DOM,targetevent tersebut diubah menjadi elemen host, bukan sumber aslinya.- Dalam contoh ini,
event.targetdi dalamShadow DOMadalah elemenbuttonyang sebenarnya, tetapi di luarShadow DOM, itu digantikan dengan elemen hostdiv.
- Dalam contoh ini,
Shadow DOM dan Elemen Kustom
Shadow DOM dan elemen kustom adalah komponen utama dari Web Components. Mereka adalah teknologi yang digunakan untuk membuat komponen UI yang dapat digunakan kembali 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 berisi HTML seperti berikut:.
1<my-card></my-card>- Dengan menggunakan
Shadow DOMdi dalam elemen kustom, Anda dapat membuat komponen yang dapat digunakan kembali dan tahan terhadap konflik gaya. Dalam kode ini, sebuah tag bernamamy-carddibuat dan dikaitkan dengan kelasMyCard. Elemen<p>di dalammy-cardtidak terpengaruh oleh gaya eksternal dan selalu ditampilkan dalam warna biru.
Slot: Mendistribusikan Konten Light DOM
Slot memungkinkan Anda menampilkan konten 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 berisi HTML seperti berikut:.
1<my-element>
2 <h3 slot="header">Header Content</h1>
3 <p slot="content">Main Content</p>
4</my-element>- Elemen
slotdi dalamShadow DOMakan menampilkan kontenLight DOMyang memiliki atributslotyang sesuai.
Kesimpulan
Shadow DOM adalah alat penting untuk membangun komponen web yang kuat, dapat digunakan kembali, dan mudah dikelola. Dengan mengen kapsulasi gaya dan fungsionalitas, ini mengurangi potensi konflik dan menyederhanakan pengelolaan kode.
Anda dapat mengikuti artikel di atas menggunakan Visual Studio Code di saluran YouTube kami. Silakan periksa juga saluran YouTube kami.