JavaScript'te Shadow DOM
Bu makale, JavaScript'te Shadow DOM'u açıklar.
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>
Shadow DOM
'u Anlamak
Shadow DOM
, stiller ve DOM yapılarını bileşenler içinde kapsüllemenizi sağlayan Web Components standardının güçlü bir özelliğidir. Bu özellik, bileşenler ile ana belge arasındaki stil ve komut dosyası karışıklığını önler.
JavaScript'te Shadow DOM
Shadow DOM
, normal bir DOM elementine bağlanan sınırlandırılmış bir DOM ağacı oluşturmanın bir yolunu sağlar. Bu shadow ağacı genel belgeden izole edilmiştir; harici stiller ve komut dosyaları bunu etkileyemez ve dahili stilleri ile komut dosyaları da dışarı sızmaz.
Örneğin, Shadow DOM
kullanarak bir özel düğme bileşeni oluşturursanız, stilleri sayfadaki diğer nesneleri etkilemez. Benzer şekilde, aynı sınıf adına sahip öğeler çakışmaz.
Shadow DOM
dışındaki normal HTML içeriğine Light DOM
denir.
Shadow DOM
'un Faydaları
-
Kapsülleme
Shadow DOM
, stil ve işlevselliği ayırarak, global stil ve betiklerle çakışmaları önler.
-
Yeniden Kullanılabilirlik
Shadow DOM
ile oluşturulan bileşenler, stil çakışmaları konusunda endişelenmeden farklı projelerde yeniden kullanılabilir.
-
Bakım Kolaylığı
- Kapsülleme, bileşenin mantığını ve stilini bağımsız hale getirir, bu da hata ayıklama ve bakımı kolaylaştırır.
Shadow DOM
Oluşturmak
Shadow DOM
kullanmak için bir HTML elemanına shadow root eklemeniz gerekir. İşte basit bir örnek:.
1// Select the host element
2const hostElement = document.querySelector('#shadow-host');
3
4// Attach a shadow root
5const shadowRoot = hostElement.attachShadow({ mode: 'open' });
Açıklama
Bu kod aşağıdaki öğeleri içerir:.
-
Barındırıcı Öğesi
- Shadow root'un bağlandığı normal bir DOM öğesi (bu örnekte,
#shadow-host
).
- Shadow root'un bağlandığı normal bir DOM öğesi (bu örnekte,
-
Shadow Root
attachShadow
kullanılarak oluşturulan shadow ağacının kökü.
-
Mod
open
modunda, harici JavaScriptelement.shadowRoot
aracılığıyla shadow root'a erişebilir. Diğer yandan,kapalı
(closed) mod erişime izin vermez.
Shadow DOM
İçindeki Stil Tanımları
Shadow DOM
kendi stil kapsama alanına sahiptir. Gölge ağacı içinde tanımlanan stiller yalnızca o ağaçtaki öğelere uygulanır. İşte bir örnek:.
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`;
Ana belgede çakışan stiller olsa bile, bunlar shadow tree içindeki paragrafı etkilemez.
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`;
Shadow DOM
içindeki paragraf yeşil kalır, dışarıdaki ise kırmızı olur.
Shadow DOM
içindeki olaylar
Shadow DOM
içindeki olaylar, düzenli DOM olaylarına benzer, ancak kapsülleme nedeniyle yayılma açısından farklı davranabilir.
İşte bir örnek:.
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});
- Düğmeye tıklandığında her iki dinleyici de tetiklenir ve olay kabarcıklanmasının davranışı gösterilir.
- Bir olay
Shadow DOM
içinde tetiklenipLight DOM
'a ulaştığında, olayıntarget
ı orijinal kaynağı yerine ana elemana yeniden yazılır.- Bu örnekte,
Shadow DOM
içindeevent.target
gerçekbutton
öğesidir, ancakShadow DOM
dışında bu değer anadiv
elementiyle değiştirilir.
- Bu örnekte,
Shadow DOM
ve Özel Öğeler
Shadow DOM
ve özel öğeler, Web Components
'ın ana bileşenleridir. Yeniden kullanılabilir ve kapsüllenmiş arayüz bileşenleri oluşturmak için kullanılan teknolojilerdir.
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);
Ana belge şu şekilde bir HTML içerir:.
1<my-card></my-card>
- Özel öğeler içinde
Shadow DOM
kullanarak, stil çakışmalarına karşı dirençli, yeniden kullanılabilir bileşenler oluşturabilirsiniz. Bu kodda,my-card
adında bir etiket oluşturulur veMyCard
sınıfıyla ilişkilendirilir.my-card
içindeki<p>
öğesi harici stillerden etkilenmez ve her zaman mavi olarak görüntülenir.
Slotlar: Light DOM
İçeriğinin Dağıtılması
Slotlar, Light DOM
içeriğini Shadow DOM
içine yansıtmanıza olanak tanır. İşte bir örnek:.
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);
Ana belge şu şekilde bir HTML içerir:.
1<my-element>
2 <h3 slot="header">Header Content</h1>
3 <p slot="content">Main Content</p>
4</my-element>
Shadow DOM
içindekislot
öğesi, ilgilislot
özniteliğine sahipLight DOM
içeriğini gösterir.
Sonuç
Shadow DOM
, sağlam, yeniden kullanılabilir ve sürdürülebilir web bileşenleri oluşturmak için hayati bir araçtır. Stilleri ve işlevselliği kapsülleyerek uyuşmazlık olasılığını azaltır ve kod tabanı yönetimini basitleştirir.
Yukarıdaki makaleyi, YouTube kanalımızda Visual Studio Code'u kullanarak takip edebilirsiniz. Lütfen YouTube kanalını da kontrol edin.