1. Document Object Model (DOM) Nedir?

DOM (Document Object Model), tarayıcı tarafından oluşturulan, HTML ve XML belgelerinin bir temsilidir. Web sayfasındaki tüm elementlerin hiyerarşik bir ağaç yapısı olarak modellenmesidir.

Bu sayede JavaScript ile sayfadaki öğelere erişebilir, onları değiştirebilir veya yeni öğeler ekleyebiliriz.

DOM Ağaç Yapısı

Her HTML etiketi bir node (düğüm) olarak temsil edilir ve bu düğümler arasında ebeveyn-çocuk ilişkileri vardır.

<!DOCTYPE html>
<html>
<head>
    <title>Örnek Sayfa</title>
</head>
<body>
    <h1>Başlık</h1>
    <p>Bu bir paragraf.</p>
</body>
</html>

DOM neden önemli?

  • Dinamik içerik: JavaScript ile sayfa yapısını değiştirme, yeni içerik ekleme gibi işlemler yapılabilir
  • Kullanıcı etkileşimi: Sayfayı interaktif hale getirir, kullanıcı hareketlerine tepki verir
  • Web geliştirme: Modern web uygulamalarının temelini oluşturur

2. DOM Seçicileri

DOM manipülasyonuna başlamadan önce, sayfadaki öğeleri nasıl seçeceğimizi bilmeliyiz.

Temel Seçiciler

let idSecim = document.getElementById("kutu");
let classSecim = document.getElementsByClassName("kirmizi");
let tagSecim = document.getElementsByTagName("div");
let querySecim = document.querySelector(".kirmizi.kutu");
let queryAllSecim = document.querySelectorAll("div");

querySelector vs querySelectorAll farkı:

  • querySelector: Belirtilen CSS seçiciye uyan ilk öğeyi döndürür
  • querySelectorAll: Belirtilen CSS seçiciye uyan tüm öğeleri NodeList olarak döndürür

3. DOM Manipülasyonu

3.1. İçerik Değiştirme

let baslik = document.getElementById("baslik");
baslik.textContent = "Yeni Başlık";

Güvenlik notu: innerHTML kullanırken XSS (Cross-Site Scripting) riskine dikkat. Kullanıcıdan gelen ham veriyi innerHTML’e direkt koymak, zararlı kod çalıştırılmasına yol açabilir. Güvenli alternatifler: textContent veya innerText (bunlar HTML çalıştırmaz).

3.2. Stil Değiştirme

baslik.style.color = "blue";
baslik.style.fontSize = "24px";

3.3. Sınıf Ekleme / Kaldırma

baslik.classList.add("vurgula");
baslik.classList.remove("eski-sinif");
baslik.classList.toggle("gizli");

3.4. Yeni Eleman Ekleme

let yeniParagraf = document.createElement("p");
yeniParagraf.textContent = "Bu yeni bir paragraf.";

let govde = document.querySelector("body");
govde.appendChild(yeniParagraf);

3.5. Eleman Silme

let silinecekEleman = document.getElementById("silinecek");
silinecekEleman.parentNode.removeChild(silinecekEleman);

4. Etkinlikler ve Etkinlik Dinleyicileri

Web sayfaları ile kullanıcı etkileşimini yönetmek için etkinlikleri kullanırız.

Sık Kullanılan Etkinlikler

4.1. Etkinlik Dinleyicisi Ekleme

let buton = document.getElementById("buton");
buton.addEventListener("click", function() {
    alert("Butona tıkladınız!");
});

4.2. Event Nesnesi

Etkinlik fonksiyonlarına geçilen otomatik bir nesnedir ve etkinlik hakkında bilgi taşır:

buton.addEventListener("click", function(event) {
    console.log(event.target); // Etkinliği tetikleyen öğe
});

addEventListener neden satır içi (onclick) tanımlamadan iyidir?

  • Aynı öğeye birden fazla dinleyici ekleyebilirsiniz
  • JS’i HTML’den ayırarak temiz yapı sağlar
  • removeEventListener ile dinleyiciyi gerektiğinde kaldırabilirsiniz
  • Olayın bağlamını (this) daha esnek kontrol edebilirsiniz

5. Form İşlemleri ve Doğrulama

5.1. Forma Erişim ve Değer Alma

let form = document.getElementById("form");
let kullaniciAdi = document.getElementById("kullaniciAdi");
let sifre = document.getElementById("sifre");

form.addEventListener("submit", function(event) {
    event.preventDefault(); // Formun otomatik gönderimini engeller

    console.log("Kullanıcı Adı:", kullaniciAdi.value);
    console.log("Şifre:", sifre.value);
});

5.2. Form Doğrulama

form.addEventListener("submit", function(event) {
    event.preventDefault();

    if (kullaniciAdi.value === "") {
        alert("Kullanıcı adı boş olamaz!");
        return;
    }

    if (sifre.value.length < 6) {
        alert("Şifre en az 6 karakter olmalıdır!");
        return;
    }

    console.log("Form başarılı bir şekilde gönderildi.");
});

event.preventDefault() ne işe yarar?

Bir olayın varsayılan davranışını durdurur. Tarayıcının otomatik olarak gerçekleştireceği işlemi engellemek için kullanılır:

  • Form gönderimini durdurmak (sayfa yenilenmesin diye)
  • Link tıklamasını engellemek (sayfa yönlendirmesin diye)

Pratik Sorular

Soru 1: Bir listeye (<ul>) input’tan yeni <li> ekleyen bir kod yazınız (Enter’a basınca da çalışsın).

const addItem = () => {
    const input = document.querySelector('#itemInput');
    const itemList = document.querySelector('#itemList');
    const newItemText = input.value.trim();

    if (newItemText) {
        const newItem = document.createElement('li');
        newItem.textContent = newItemText;
        itemList.appendChild(newItem);
        input.value = '';
    } else {
        alert('Lütfen bir değer giriniz.');
    }
};

const addButton = document.querySelector('#testbutton');
addButton.addEventListener('click', addItem);

// Enter tuşu için
const input = document.querySelector('#itemInput');
input.addEventListener('keypress', (e) => {
    if (e.key === 'Enter') addItem();
});

Soru 2: Butona her tıkladığında sayfada rastgele bir arka plan rengi oluşturan bir kod yazınız.

const getRandomColor = () => {
    const letters = '0123456789ABCDEF';
    let color = '#';
    for (let i = 0; i < 6; i++) {
        color += letters[Math.floor(Math.random() * 16)];
    }
    return color;
};

const changeBackground = () => {
    document.body.style.backgroundColor = getRandomColor();
};

const backgroundButton = document.querySelector('#background_change');
backgroundButton.addEventListener('click', changeBackground);

Soru 3: E-posta ve şifre formu için doğrulama yazınız (e-posta formatı

document.addEventListener('DOMContentLoaded', () => {
    const form = document.querySelector('#loginForm');
    const emailInput = document.querySelector('#email');
    const passwordInput = document.querySelector('#password');
    const emailError = document.querySelector('#emailError');
    const passwordError = document.querySelector('#passwordError');
    const formMessage = document.querySelector('#formMessage');

    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;

    form.addEventListener('submit', (e) => {
        e.preventDefault();

        emailError.textContent = '';
        passwordError.textContent = '';
        formMessage.textContent = '';

        let isValid = true;
        const emailValue = emailInput.value.trim();
        const passwordValue = passwordInput.value.trim();

        if (!emailRegex.test(emailValue)) {
            emailError.textContent = 'Lütfen geçerli bir e-posta adresi giriniz.';
            isValid = false;
        }

        if (passwordValue.length < 8) {
            passwordError.textContent = 'Şifre en az 8 karakter olmalıdır.';
            isValid = false;
        }

        if (isValid) {
            formMessage.textContent = 'Form başarıyla gönderildi!';
            form.reset();
        }
    });
});

Günün Özeti

Bugün JavaScript ile web sayfalarını nasıl dinamik hale getirebileceğimizi öğrendik:

Yarın, Gün 4’te asenkron JavaScript ve API’lar konusuna odaklanacağız. Bu, modern web uygulamalarında veri çekmek ve asenkron işlemleri yönetmek için çok önemli bir konu.