Giriş
Web sayfasındaki tüm HTML öğeleri, JavaScript tarafından bir ağaç yapısı olarak temsil edilir; bu yapıya Document Object Model (DOM) denir. DOM sayesinde sayfadaki öğeleri seçebilir, içeriğini değiştirebilir ve yeni öğeler ekleyebilirsiniz. Temel kavramlar ve daha fazlası için Patika.dev'in ilgili dersine bakabilirsiniz: Patika.dev – Document Object Model (DOM) Nedir.
DOM nedir? Kısa açıklama
DOM, bir HTML belgesinin programatik temsilidir. Her element bir düğüm (node) olarak kabul edilir ve JavaScript ile bu düğümlere erişip üzerinde değişiklik yapabilirsiniz. Bu makalede örneklerle öğe seçme, var olan öğeyi değiştirme, yeni öğe ekleme ve iyi uygulama ipuçları gösterilecektir.
Öğe seçme yöntemleri
Öğe seçme, DOM manipülasyonunun ilk adımıdır. Aşağıda en yaygın yöntemler ve kısa örnekleri yer alıyor.
1) document.getElementById()
Tek bir id'ye sahip öğeyi döndürür. Dönen değer null olabilir, bu yüzden null kontrolü yapmak önemlidir.
const titleEl = document.getElementById('page-title');
if (titleEl) {
titleEl.textContent = 'Yeni Başlık';
}
2) document.getElementsByClassName() ve getElementsByTagName()
Bu metotlar bir HTMLCollection döndürebilir; bu koleksiyon sayfa değişikliklerine göre canlı (live) güncellenebilir. Liste üzerindeki işlemler için diziyi kopyalamak bazen faydalıdır.
const items = document.getElementsByClassName('card');
// items bir HTMLCollection'dur; for döngüsü ile işleyin
3) document.querySelector() ve querySelectorAll()
CSS seçicileri kullanma esnekliği sağlar. querySelector tek bir öğe, querySelectorAll ise statik bir NodeList döndürür; NodeList üzerinde forEach kullanılabilir.
const firstButton = document.querySelector('.btn');
const allButtons = document.querySelectorAll('.btn');
allButtons.forEach(btn => btn.classList.add('highlight'));
İpucu: Hangi metodu kullanacağınızı seçerken ihtiyaç (tek öğe mi, toplu işlem mi) ve performans beklentisini göz önünde bulundurun. Genel olarak CSS seçicileri esneklik sağlar.
Öğe değiştirme: içerik, özellik ve sınıf güncellemeleri
Seçtiğiniz öğenin içeriğini ve özelliklerini değiştirmek için birkaç temel API vardır.
textContent, innerText ve innerHTML
textContent ve innerText arasındaki farklar vardır; textContent, düğümdeki tüm metni ham olarak verir ve genelde metin güncellemeleri için tercih edilir. innerHTML, HTML içeriğini doğrudan değiştirir ve HTML parçalaması yapar.
const p = document.querySelector('#intro');
p.textContent = 'Merhaba! Bu içerik güvenli bir şekilde eklendi.';
// innerHTML yalnızca bilinçli ve sanitized içerik için kullanılmalı
Özellikler ve sınıflar
Özellikleri değiştirmek için setAttribute/getAttribute veya doğrudan property'leri kullanabilirsiniz. classList, sınıf yönetimi için kullanışlıdır.
const img = document.querySelector('img.logo');
img.setAttribute('alt', 'Site logosu');
img.classList.add('visible');
img.classList.toggle('hidden');
Yeni öğe ekleme: createElement, append/appendChild, insertBefore
Yeni bir öğe oluştururken createElement ile öğe oluşturup içine textContent eklemek genelde tercih edilir. Kullanıcı verisini doğrudan HTML içine yazmak yerine element oluşturmak, içerik eklemek daha kontrollü olur.
Basit bir örnek: listeye öğe ekleme
const ul = document.querySelector('#todo-list');
const li = document.createElement('li');
li.textContent = userInput; // kullanıcı verisini textContent ile ekleyin
ul.appendChild(li);
Birden fazla öğeyi performanslı ekleme: DocumentFragment
Aynı anda çok sayıda öğe eklerken DocumentFragment kullanmak, tarayıcı reflow/repaint sayısını azaltır.
const frag = document.createDocumentFragment();
for (let i = 0; i < 100; i++) {
const li = document.createElement('li');
li.textContent = `Madde ${i + 1}`;
frag.appendChild(li);
}
ul.appendChild(frag);
innerHTML ile ekleme — dikkat edilmesi gerekenler
innerHTML hızlı ve kısa çözümler sağlar, ancak kullanıcıdan gelen ham HTML uygulandığında XSS riski olabilir. Mümkünse kullanıcı verisini textContent veya createElement ile ekleyin; ham HTML gerekiyorsa mutlaka sanitizasyon uygulayın.
Olay delegasyonu ve etkileşim
Bir liste üzerindeki birçok öğeye ayrı ayrı event listener eklemek yerine, üst kapsayıcıya (container) tek listener koyup tıklanan hedefi kontrol etmek (event delegation) daha verimlidir.
const list = document.querySelector('#todo-list');
list.addEventListener('click', (e) => {
const li = e.target.closest('li');
if (!li) return;
console.log('Tıklanan madde:', li.textContent);
});
Performans ve iyi uygulama ipuçları
- Birden çok DOM yazımı yapacaksanız, önce değişiklikleri bellek üzerinde hazırlayıp tek seferde DOM'a uygulayın (DocumentFragment, innerHTML tek setleme gibi).
- Okuma (offsetWidth, getComputedStyle) ve yazma (style, classList) işlemlerini karıştırmamaya çalışın; sıralı okuma-yazma tarayıcıda yeniden hesaplamalara (reflow) neden olabilir.
- Büyük DOM ağaçlarında seçici kullanımını daraltın (örneğin
#container .itemyerine doğrudan referans saklamak) ve gerektiğinde değişkenlere atayıp tekrar kullanın. - Animasyonlar için requestAnimationFrame kullanın.
Erişilebilirlik ve güvenlik notları
DOM manipülasyonu yaparken semantik HTML ve ARIA özniteliklerini korumaya dikkat edin. Kullanıcı girdisini doğrudan innerHTML ile koymaktan kaçının; metin eklemek için textContent tercih edilmelidir. Dinamik değişikliklerden sonra ekran okuyucular için uygun aria-live veya odak yönetimi eklenmelidir.
Kontrol listesi (Hızlı)
- Seçmeden önce öğenin sayfada mevcut olduğundan emin olun (null kontrolü).
- Kullanıcı verisini innerHTML ile eklemeyin; textContent veya createElement kullanın.
- Toplu eklemelerde DocumentFragment kullanın.
- Event delegation ile fazla listener eklemesini önleyin.
- Değişiklik sonrası gerektiğinde ARIA ve odak yönetimine dikkat edin.
Kaynaklar ve ileri okuma
Bu rehaz, DOM'un ne olduğunu ve temel manipülasyonları açıklayan kaynaklardan derlenmiştir. Temel DOM kavramları için Patika.dev kursuna bakabilirsiniz: https://academy.patika.dev/en/courses/javascript/document-object-model-dom-nedir. Ayrıca tarayıcı API dokümantasyonları ve MDN Web Docs, daha derin referans için faydalıdır.