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 DOMile 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
attachShadowkullanılarak oluşturulan shadow ağacının kökü.
-
Mod
openmodunda, harici JavaScriptelement.shadowRootaracı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 DOMiç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 DOMiçinde tetiklenipLight DOM'a ulaştığında, olayıntargetı orijinal kaynağı yerine ana elemana yeniden yazılır.- Bu örnekte,
Shadow DOMiçindeevent.targetgerçekbuttonöğesidir, ancakShadow DOMdışında bu değer anadivelementiyle 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 DOMkullanarak, stil çakışmalarına karşı dirençli, yeniden kullanılabilir bileşenler oluşturabilirsiniz. Bu kodda,my-cardadında bir etiket oluşturulur veMyCardsınıfıyla ilişkilendirilir.my-cardiç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 DOMiçindekislotöğesi, ilgilislotözniteliğine sahipLight DOMiç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.