Gereksinimler ve Ön Hazırlık
Bu projeyi hayata geçirmek için temel düzeyde HTML, CSS ve JavaScript bilgisine sahip olmanız yeterlidir. Herhangi bir dış kütüphane kullanmadan, saf (Vanilla) JavaScript ile tarayıcıların sunduğu yerel API'leri kullanacağız. Çalışma ortamınızda bir metin editörü (VS Code önerilir) ve modern bir web tarayıcısı (Chrome, Firefox veya Edge) bulunması yeterlidir.
- HTML5 yapısına sahip bir web sayfası.
- Temel CSS bilgisi (menü tasarımı için).
- Tarayıcı konsolu üzerinden hata ayıklama yeteneği.
Adım 1: HTML Yapısını ve Hedef Alanı Belirleme
Öncelikle, oluşturacağımız içindekiler tablosunun yerleşeceği bir konteyner (kapsayıcı) elementine ihtiyacımız var. Bu element, JavaScript tarafından dinamik olarak doldurulacaktır.
Giriş Bölümü
Kurulum Adımları
Burada #toc-list ID'sine sahip ul etiketi, JavaScript kodumuzun hedefi olacaktır. İçeriğinizi #content içerisinde tutmak, sadece ilgili başlıklara odaklanmamızı sağlar.
Adım 2: Başlıkları JavaScript ile Seçme ve İterasyon
Sayfadaki tüm h2 ve h3 etiketlerini seçmek için querySelectorAll metodunu kullanacağız. Bu metod, DOM üzerinde bir NodeList döndürür.
const headings = document.querySelectorAll('#content h2, #content h3');
const tocList = document.querySelector('#toc-list');
headings.forEach((heading, index) => {
// Her başlığa benzersiz bir ID atıyoruz
const id = 'heading-' + index;
heading.id = id;
// Liste elemanı oluşturma
const listItem = document.createElement('li');
const link = document.createElement('a');
link.textContent = heading.textContent;
link.href = '#' + id;
listItem.appendChild(link);
tocList.appendChild(listItem);
});
Bu kod bloğu, her başlığa otomatik bir id atar ve bu ID'ye yönlendiren bir bağlantı (anchor) oluşturur. Böylece kullanıcı bağlantıya tıkladığında ilgili başlığa otomatik olarak kaydırılır.
Adım 3: İçindekiler Tablosunu Hiyerarşik Yapılandırma
Sadece h2 ve h3 etiketlerini düz bir liste yapmak yerine, h3 etiketlerini h2'lerin altına yuvalamak (nesting) daha profesyonel bir görünüm sağlar. Bunun için başlığın türünü kontrol eden bir mantık kurmalıyız.
let currentParentList = tocList;
headings.forEach((heading, index) => {
const id = 'section-' + index;
heading.id = id;
const li = document.createElement('li');
const a = document.createElement('a');
a.textContent = heading.textContent;
a.href = '#' + id;
li.appendChild(a);
if (heading.tagName === 'H2') {
tocList.appendChild(li);
// Yeni bir alt liste oluşturma hazırlığı
const subList = document.createElement('ul');
li.appendChild(subList);
currentParentList = subList;
} else if (heading.tagName === 'H3') {
currentParentList.appendChild(li);
}
});
Bu yöntemle, h2 etiketleri ana liste elemanları olurken, h3 etiketleri bir alt listede yer alır. Bu, kullanıcıların içerik hiyerarşisini anlamasını kolaylaştırır.
Adım 4: Kullanıcı Deneyimi ve CSS İyileştirmeleri
Dinamik olarak oluşturulan bu yapının şık görünmesi için CSS kullanmalıyız. Özellikle scroll-behavior: smooth özelliği, tıklama sonrası sayfadaki kaydırma hareketini yumuşatır.
/* CSS Dosyanıza ekleyin */
html {
scroll-behavior: smooth;
}
#toc-container {
background: #f9f9f9;
padding: 20px;
border-radius: 8px;
}
#toc-list ul {
margin-left: 20px;
list-style-type: disc;
}
Bu CSS kuralları, içindekiler tablosunun görsel olarak içerikten ayrılmasını sağlar ve kullanıcıya modern bir akış deneyimi sunar.
Adım 5: Güvenlik ve Performans Optimizasyonu
Dinamik içerik oluştururken, özellikle kullanıcıdan gelen verileri işliyorsanız XSS (Cross-Site Scripting) saldırılarına karşı dikkatli olmalısınız. textContent kullanımı, HTML etiketlerinin metin olarak işlenmesini sağlar ve zararlı scriptlerin çalıştırılmasını önler.
Kritik Uyarı: Dinamik içerik oluştururken aslainnerHTMLmetodunu, güvenilir olmayan verilerle kullanmayın. Kullanıcı girdilerini her zaman sanitize edin (temizleyin) veyatextContenttercih edin.
| Yöntem | Avantajı | Dezavantajı |
|---|---|---|
| Statik HTML | Basit, SEO dostu | Bakımı zor, güncelleme gerektirir |
| JavaScript Dinamik | Otomatik, ölçeklenebilir | JavaScript kapalıysa çalışmaz |
Sıkça Sorulan Sorular
JavaScript kapalıysa içindekiler tablosu görünür mü?
Hayır, JavaScript tarafından oluşturulan içerikler tarayıcıda JS devre dışıysa görünmez. Bu nedenle, kritik içerikler için sunucu taraflı (SSR) çözümler tercih edilebilir.
Neden h2 ve h3 etiketlerini seçiyoruz?
Genellikle makalelerde ana başlıklar h2, alt başlıklar h3 olarak kullanılır. Bu, hem SEO hem de dokümantasyon standartları için en yaygın kabul gören hiyerarşidir.
Sayfa yüklendikten sonra yeni başlık eklenirse ne olur?
Yukarıdaki kod sayfa yüklendiğinde (DOMContentLoad) çalışır. Eğer içerik AJAX ile sonradan geliyorsa, fonksiyonu veriler yüklendikten sonra tekrar tetiklemeniz gerekir.
Arama motorları bu dinamik yapıyı görür mü?
Modern arama motorları JavaScript'i işleyebilmektedir. Ancak, SEO için en iyi pratik, içeriğin HTML içerisinde hazır gelmesidir; bu yöntem daha çok kullanıcı deneyimi odaklıdır.
Bu yapı mobil cihazlarda nasıl görünür?
CSS ile #toc-container elementine display: none verip, bir "İçindekiler" butonu ile görünürlüğünü kontrol ederek mobil uyumlu (responsive) hale getirebilirsiniz.
Yasal Sorumluluk Reddi: Bu rehber tamamen eğitim amaçlıdır. Uygulamanızda oluşabilecek veri kaybı veya performans sorunlarından kullanıcı sorumludur. Üretim ortamında (production) kodunuzu mutlaka test edin.
İleri Seviye İpucu: Intersection Observer ile Aktif Başlığı Vurgulama
Kullanıcı sayfayı kaydırdığında, o an okuduğu başlığın içindekiler tablosunda otomatik olarak işaretlenmesi, profesyonel bir kullanıcı deneyimi sunar. Bunun için Intersection Observer API kullanarak, hangi başlığın görünür alana girdiğini takip edebiliriz.
const observerOptions = {
root: null,
rootMargin: '0px',
threshold: 1.0
};
const observer = new IntersectionObserver((entries) => {
entries.forEach(entry => {
if (entry.isIntersecting) {
const id = entry.target.getAttribute('id');
document.querySelectorAll('.toc-link').forEach(link => {
link.classList.remove('active');
if (link.getAttribute('href') === `#${id}`) {
link.classList.add('active');
}
});
}
});
}, observerOptions);
document.querySelectorAll('h2, h3').forEach(heading => {
observer.observe(heading);
});
Bu kod bloğu, sayfadaki tüm h2 ve h3 etiketlerini gözlemler. Başlık ekranın üst kısmına ulaştığında, ilgili bağlantıya active sınıfını ekler. CSS tarafında bu sınıfa color: blue; font-weight: bold; gibi stiller vererek görsel bir geri bildirim sağlayabilirsiniz.
Hata Ayıklama ve Yaygın Karşılaşılan Sorunlar
Dinamik bir yapı kurarken, özellikle DOM manipülasyonu sırasında bazı hatalarla karşılaşmanız olasıdır. İşte en sık rastlanan durumlar ve çözüm yolları:
- Eksik ID Özellikleri: Eğer başlıklarınızın
idniteliği yoksa, bağlantılar çalışmayacaktır. JavaScript kodunuzun başında her başlığa otomatik biridatandığından emin olun. - Zamanlama Sorunları: Eğer içeriğiniz bir API'den veya
fetchile geliyorsa, tabloyu oluşturma fonksiyonunu veri yüklendikten sonra çağırmalısınız. - CSS Çakışmaları: İçindekiler tablosunun
position: fixedolduğu durumlarda, sayfa içeriğinin üzerine binmemesi için ana kapsayıcıyapadding-leftveyamargin-lefteklemeyi unutmayın.
Aşağıdaki tablo, hata ayıklama sürecinde kontrol etmeniz gereken temel parametreleri özetlemektedir:
| Sorun | Olası Neden | Çözüm |
|---|---|---|
| Linkler çalışmıyor | ID eşleşmesi yok | heading.id değerini kontrol edin |
| Tablo boş görünüyor | DOM hazır değil | DOMContentLoaded olayını kullanın |
| Stil bozuluyor | Z-index çakışması | Tabloya z-index: 1000 verin |
Profesyonel Not: Karmaşık ve çok uzun sayfalarda, içindekiler tablosunu bir "açılır-kapanır" (accordion) yapısına dönüştürmek, mobil cihazlardaki ekran karmaşasını ciddi oranda azaltacaktır.
Sonuç
JavaScript ile web sayfası için dinamik içindekiler tablosu oluşturmak, hem kodunuzu temiz tutmanızı sağlar hem de ziyaretçilerinizin sayfa üzerinde geçirdiği süreyi artırır. Bu rehberde öğrendiğiniz DOM manipülasyon tekniklerini, daha karmaşık projelerinizde (örneğin otomatik başlık numaralandırma veya "sayfanın üstüne dön" butonları) genişleterek kullanabilirsiniz. Bir sonraki adım olarak, Intersection Observer API'sini kullanarak sayfayı kaydırdıkça içindekiler tablosundaki aktif başlığın otomatik olarak vurgulanmasını sağlayan bir özellik eklemeyi deneyebilirsiniz.

Yorumlar (0)
Yorum Yaz