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 DOM
memisahkan gaya dan fungsi, sehingga mencegah konflik dengan gaya dan skrip global.
-
Dapat digunakan kembali
- Komponen yang dibangun dengan
Shadow DOM
dapat 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, modeclosed
tidak 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 DOM
tetap 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 DOM
naik keLight DOM
,target
event tersebut diubah menjadi elemen host, bukan sumber aslinya.- Dalam contoh ini,
event.target
di dalamShadow DOM
adalah elemenbutton
yang 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 DOM
di dalam elemen kustom, Anda dapat membuat komponen yang dapat digunakan kembali dan tahan terhadap konflik gaya. Dalam kode ini, sebuah tag bernamamy-card
dibuat dan dikaitkan dengan kelasMyCard
. Elemen<p>
di dalammy-card
tidak 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
slot
di dalamShadow DOM
akan menampilkan kontenLight DOM
yang memiliki atributslot
yang 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.