Bir süre önce JavaScript tarafında ufak bir refactor yaparken kendimi yine aynı sorunun önünde buldum: querySelector() burada gerçekten şart mı? Açık konuşayım, çoğu işte değil (ki bu çoğu kişinin gözünden kaçıyor). Hani elimiz otomatik olarak o metoda gidiyor ya — ben de uzun süre tam öyle yaptım. Sonra şunu fark ettim: DOM zaten elinde yeterince bilgi veriyor. Biraz dikkatle bakınca, tarayıcının sunduğu hazır referanslarla — yani hiçbir selector yazmadan — çok daha sade ve okunur bir yapı kurabiliyorsunuz; hem de düşündüğünüzden hızlı.
Geçen yıl 2025’in Şubat ayında, İstanbul’da küçük bir ajans projesinde çalışırken bu yaklaşımı ilk kez ciddi ciddi denedim. Ekipteki arkadaşlardan biri “Bu kadar çok selector neden var?” diye sormuştu. Ben de o gün oturup kodu baştan taradım. Şaşırdım açıkçası. Birkaç yerde querySelector yerine doğrudan children, parentElement ve nextElementSibling ile ilerleyince hem kod kısaldı hem de zihinsel yük bayağı düştü.
Neyse uzatmayalım; mesele sadece “ben sevmiyorum” meselesi değil. İşin aslı şu: DOM ağacını bir nesne gibi düşünürseniz zaten elinizde dolaşabileceğiniz pek çok kapı var. Yani bu yazıda “selector kullanmayın” demeyeceğim — dürüst olayım, bazı durumlarda hâlâ lazım. Ama her şeyi onunla çözmeye çalışmak da biraz gereksiz şişkinlik yaratıyor (inanın bana)
Neden QuerySelector Her Zaman En İyi Yol Değil?
document.querySelector() kulağa pratik geliyor, evet. Tek satırda istediğin elemana gidiyorsun; CSS selector yazıyorsun ve mesele bitiyor gibi duruyor. Fakat pratikte işler o kadar temiz değil. Selector string’i uzadıkça bakım maliyeti artıyor, hata ayıklama uzuyor ve küçük bir HTML değişikliği bile — inanması güç ama — zincirleme sorun çıkarabiliyor.
Hani, Bunu 2024 sonbaharında Ankara’da yürüttüğüm bir dashboard projesinde bayağı net gördüm. Tasarım ekibi buton sınıfını değiştirdi, bazı scriptler patladı. Kod doğruydu aslında… ama kırılgan olduğu için doğru kalamadı! O gün anladım ki, DOM içindeki konumu belli olan elemanlarda selector yerine ilişkisel erişim çoğu zaman çok daha sağlam duruyor.
Bakın, Kısacası: selector mantığı dış dünyaya açılan tabela gibi; işe yarar ama tabelanın yerini değiştirirseniz kapıyı kaybedersiniz. DOM referansları ise binanın iç merdiveni gibi çalışıyor — özellikle içeride kalmanız gereken senaryolarda.
firstElementChild ile lastElementChild çoğu zaman aynı düğümü gösterir. Güzel görünüyor ama biraz tehlikeli; yarın yeni bir öğe eklenirse bütün mantık kayabilir.
Daha Az Selector, Daha Çok Doğrudan Bağlantı
Benim tercih ettiğim yaklaşım şu: önce merkezi bir başlangıç noktası belirlemek, sonra oradan DOM’u dallandırarak okumak. Mesela body’den başlarım, wrapper’a giderim, sonra içerik alanına geçerim. Bu yöntem özellikle büyük arayüzlerde ciddi rahatlık veriyor. Her adımı ayrı ayrı düşünebiliyorsunuz; kafanızda net bir yol haritası oluşuyor.
Editör masasındayken bunu test ettiğimde ilk dikkatimi çeken şey şuydu: state yönetimiyle karışan UI taraflarında selector sayısı azaldıkça kodun niyeti daha görünür oluyor. Yani “hangi öğeyi seçiyorum?” sorusu azalıyor, “bu öğenin ebeveyni ne?” sorusu öne çıkıyor (evet, doğru duydunuz). İşin aslı bu kadar basit. Ama etkisi fena değil.
Açıkçası, Kendi notlarımda bunun için sık kullandığım bazı DOM özellikleri var:
document.activeElementalert.target‘a eşlik eden bağlam bilgisifirstElementChildlastElementChildchildren.length- sibling/parent ilişkileri
nextElementSiblingvepreviousElementSibling
Nerede İşe Yarıyor?
Bilmem anlatabiliyor muyum, Küçük. Orta ölçekli projelerde bu yöntem bayağı rahat ettiriyor çünkü komponent ağacı zaten belli oluyor. Toolbar, sidebar veya modal gibi kendi içinde kapalı kalan parçalarda direkt ilişki üzerinden gitmek hızlı sonuç veriyor. Denediyseniz biliyorsunuzdur. Bu konuyla ilgili Zoxide ile Terminalde Kayıp Gitmemek: Hızlı Gezinme Rehberi yazımıza da göz atmanızı tavsiye ederim. Daha fazla bilgi için Archon neden zirvede? Yapay zekâda iki ayrı yol ayrımı yazımıza bakabilirsiniz.
Şunu fark ettim: Büyük enterprise projelerde ise tablo biraz değişiyor. Ekip çok kişiyle çalışıyorsa. Markup sık sık oynuyorsa bağlantıları iyi belgelemek gerekiyor; yoksa “ben buraya nasıl geldim?” sorusu hızla ortaya çıkıyor — ve hiç hoş olmuyor, inan bana.
Nerede Ters Tepebilir?
Eğer element yapısı sürekli değişiyorsa ya da dışarıdan inject edilen içerikle uğraşıyorsanız doğrudan sibling/child zinciri kurmak risk taşıyor. Burada querySelector hâlâ kullanışlı kalıyor. Yani mesele fanatiklik değil, araç seçimi. Chrome’da Birikmiş Yer İntihar Etmeden: Aftermark Ne Yapıyor? yazımızda bu konuya da değinmiştik.
function getDomObjects() {
const body = document.body;
const wrap = body.firstElementChild;
const topSection = wrap?.firstElementChild;
const mainArea = wrap?.children[1];
const controls = wrap?.lastElementChild;
return { body, wrap, topSection, mainArea, controls };
}
Bazı Pratik Kurallar Bana Neyi Öğretti?
Dürüst olayım, ben uzun süre “ilk çocuk” fikrini hafife aldım. Oysa çoğu UI akışında güvenilir — en azından ben öyle düşünüyorum — olan tam da orası oluyor — gelecekte genişlemeye açık bırakılan nokta çoğunlukla burası çünkü (yanlış duymadınız). Mesela tek child varsa bile sadece firstElementChild ile ilerlemek, lastElementChild‘ı geleceğe saklamak bence iyi bir alışkanlık. Biraz muhafazakâr görünüyor. Ama iş görüyor.
Doğrusu, Buna karşılık sadece lastElementChild‘a yaslanmak bana birkaç kez ters döndü. En çok da de ürün sahibinin “buraya küçük bir kart daha ekleyelim” dediği anlarda sistem kırıldı — hani klasik sürpriz. O yüzden seçimleri bilerek yapmak gerekiyor, yoksa bug üretmek çocuk oyuncağına dönüyor.
Bakın, burayı atlarsanız yazının kalanı anlamsız kalır. Bir GitHub Projesinin Son %1’i: Sürümü Sağlam Kapatmak yazımızda da bu konuya değinmiştik. Kısa Vadeli Trendleri Okuyan Esnek Regresyon: ALLR Rehberi yazımızda da bu konuya değinmiştik.
| Aşama | Selector yaklaşımı | Daha direkt DOM yaklaşımı |
|---|---|---|
| Kod okunabilirliği | Düşebilir | Bazen yükselir |
| Kırılganlık | Tasarım değişince artar | Ağaç yapısı sabitse azalır |
| Ekip iletişimi | Sınıf isimlerine bağlıdır | Bileşen ilişkisine dayanır |
| Sorgu maliyeti | Sabit değildir | Daha öngörülebilir olabilir |
Küçük Proje mi Büyük Sistem mi?
Küçük startup ortamında ben bu yöntemi daha rahat öneririm çünkü ekip azdır, yapı nettir. Herkesin kafasında aynı komponent haritası vardır. Geçen mart ayında Kadıköy’de birlikte çalıştığımız iki kişilik ekibin projesinde bunu uyguladık; kod gözle görülür biçimde sadeleşti. Hele debug sırasında parent-child zinciri görmek insana resmen nefes aldırıyor.
E tabi enterprise tarafta aynı reçete birebir işlemez. Orada markup, design token sistemi, A/B testleri, feature flag’ler derken dünya büyüyor; merkezi bağlama ihtiyacınız var ama disiplin de şart. Dokümantasyon yapılmazsa altından kalkmak zorlaşır, açık konuşayım.
“Her şeyi querySelector ile çözmek kolay görünür; ta ki ilk yeniden tasarım geldiğinde sistem domino taşı gibi devrilene kadar.”
Peki Ben Bugün Ne Yapıyorum?
Bazı durumlarda kendime küçük yardımcı fonksiyonlar yazıyorum; mevcut tree içinden obje haritası çıkarıp isimlendirilmiş referanslarla ilerlemek baya iş görüyor. Dur bir saniye — aslında en sevdiğim taraf bu değil teknik olarak. Zeka dolu olması değil, pratikte hata yüzeyini küçültmesi. İşte o kısmı seviyor insan.
Bir dostum İzmir’de Mart 2026’da buna geçtiğini anlattığında “ilk hafta garip geliyor” demişti. Haklıymış.
- Lafı gevelemeden başlayacağınız merkezi düğümü seçin.
- Erişim yolunu kısa tutun. (bu kritik)
- Sadece ihtiyaç duyduğunuz ilişki tiplerini kullanın. — ciddi fark yaratıyor
- Ekleme ihtimali olan yerlerde
last‘i hemen tüketmeyin. - Sistem büyüdükçe küçük yardımcı map yapılarıyla destekleyin.
Sıkça Sorulan Sorular `querySelector()` neredeyse tamamen bırakılmalı mı?
`Hayır.` Baz
///
/// ඞ𓂀
Bu içerik işinize yaradı mı?
Benzer içerikleri kaçırmamak için beni sosyal medyada takip edin.



