Tüm blog yazıları

JavaScript DOM Events: Input ve Change Events

JavaScript DOM'da input ve change event'leriyle anlık kullanıcı etkileşimleri yaratın. Canlı arama, karakter sayacı ve form doğrulama gibi dinamik özellikler bu event'ler sayesinde hayat bulur. Farkları ve pratik kullanım örnekleri bu yazıda!

eminbasbayan6 dk okuma
JavaScript DOM input ve change event'lerini gösteren kod örneği ve bir klavye görseli.

Bir önceki makalede form submit olaylarını öğrendik. Ancak bazen kullanıcı formu göndermeden önce, yazdığı sırada bir şeyler yapmak isteriz. Canlı arama önerileri, karakter sayacı, anlık form doğrulama gibi özellikler bunun örnekleridir. İşte bu noktada input ve change event'leri devreye girer.

input vs change: Temel Fark

EventNe Zaman Tetiklenir
inputInput'un değeri her değiştiğinde (her tuş vuruşunda)
changeInput'tan çıkıldığında (blur) ve değer değişmişse

Görsel Karşılaştırma

javascript
const textInput = document.querySelector('#metin');

textInput.addEventListener('input', function() {
    console.log('INPUT:', this.value);
});

textInput.addEventListener('change', function() {
    console.log('CHANGE:', this.value);
});

Kullanıcı "Merhaba" yazarsa:

metin
INPUT: M
INPUT: Me
INPUT: Mer
INPUT: Merh
INPUT: Merha
INPUT: Merhab
INPUT: Merhaba
(Kullanıcı input'tan çıkar)
CHANGE: Merhaba

input Event Detaylı

input event'i şu durumlarda tetiklenir:

✅ Klavyeyle yazma
✅ Kopyala-yapıştır (Ctrl+V veya sağ tık menüsü)
✅ Sürükle-bırak ile metin ekleme
✅ Ses-yazı dönüştürme (speech-to-text)
✅ Otomatik tamamlama seçimi

Örnek: Karakter Sayacı

html
<textarea id="mesaj" maxlength="280"></textarea>
<p id="sayac">0 / 280 karakter</p>
javascript
const mesajAlani = document.querySelector('#mesaj');
const sayac = document.querySelector('#sayac');

mesajAlani.addEventListener('input', function() {
    const mevcutUzunluk = this.value.length;
    const maksUzunluk = this.getAttribute('maxlength');
    
    sayac.textContent = `${mevcutUzunluk} / ${maksUzunluk} karakter`;
    
    // Limite yaklaşınca uyar
    if (mevcutUzunluk >= maksUzunluk - 20) {
        sayac.style.color = 'orange';
    }
    if (mevcutUzunluk >= maksUzunluk - 10) {
        sayac.style.color = 'red';
    }
    if (mevcutUzunluk < maksUzunluk - 20) {
        sayac.style.color = 'inherit';
    }
});

Gerçek Hayat Örneği: Canlı Önizleme

Markdown editörlerinde veya blog yazarken sıkça gördüğümüz canlı önizleme özelliği:

html
<div class="editor-container">
    <div class="editor">
        <h3>Düzenle</h3>
        <textarea id="icerik" placeholder="Buraya yazın..."></textarea>
    </div>
    <div class="preview">
        <h3>Önizleme</h3>
        <div id="onizleme"></div>
    </div>
</div>
javascript
const icerikAlani = document.querySelector('#icerik');
const onizlemeAlani = document.querySelector('#onizleme');

icerikAlani.addEventListener('input', function() {
    // Basit bir dönüşüm (gerçekte markdown parser kullanılır)
    let html = this.value;
    
    // Satır sonlarını <br> yap
    html = html.replace(/\n/g, '<br>');
    
    // **kalın** metinleri <strong> yap
    html = html.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
    
    // *italik* metinleri <em> yap
    html = html.replace(/\*(.*?)\*/g, '<em>$1</em>');
    
    onizlemeAlani.innerHTML = html;
});

Gerçek Hayat Örneği: Anlık Arama Filtreleme

Bir listede anlık filtreleme yapma:

html
<input type="text" id="filtre" placeholder="Ürün ara...">
<ul id="urun-listesi">
    <li>Laptop</li>
    <li>Telefon</li>
    <li>Tablet</li>
    <li>Kulaklık</li>
    <li>Mouse</li>
    <li>Klavye</li>
    <li>Monitor</li>
</ul>
javascript
const filtreInput = document.querySelector('#filtre');
const urunListesi = document.querySelector('#urun-listesi');
const tumUrunler = urunListesi.querySelectorAll('li');

filtreInput.addEventListener('input', function() {
    const aramaMetni = this.value.toLowerCase().trim();
    
    tumUrunler.forEach(function(urun) {
        const urunAdi = urun.textContent.toLowerCase();
        
        if (urunAdi.includes(aramaMetni)) {
            urun.style.display = 'list-item';
        } else {
            urun.style.display = 'none';
        }
    });
    
    // Sonuç bulunamadıysa mesaj göster
    const gorunenler = Array.from(tumUrunler).filter(u => u.style.display !== 'none');
    if (gorunenler.length === 0) {
        // Sonuç yok mesajı ekle
    }
});

change Event Detaylı

change event'i şu durumlarda tetiklenir:

  • Text input/textarea: Kullanıcı input'tan çıktığında (blur) VE değer değişmişse
  • Checkbox: Tıklandığında (hemen)
  • Radio button: Seçildiğinde (hemen)
  • Select/dropdown: Seçim değiştiğinde (hemen)

Text Input'ta change

javascript
const isimInput = document.querySelector('#isim');

isimInput.addEventListener('change', function() {
    console.log('İsim değişti:', this.value);
    // API'ye kaydet veya doğrulama yap
});

Not: Text input'ta change event'i, kullanıcı Tab tuşuna basarak veya başka bir yere tıklayarak input'tan ayrıldığında tetiklenir.

Checkbox'ta change

html
<label>
    <input type="checkbox" id="kosullar"> Şartları kabul ediyorum
</label>
<button id="devam-btn" disabled>Devam Et</button>
javascript
const checkbox = document.querySelector('#kosullar');
const devamBtn = document.querySelector('#devam-btn');

checkbox.addEventListener('change', function() {
    if (this.checked) {
        devamBtn.disabled = false;
        devamBtn.textContent = 'Devam Et';
    } else {
        devamBtn.disabled = true;
        devamBtn.textContent = 'Önce şartları kabul edin';
    }
});

Select/Dropdown'da change

html
<select id="sehir">
    <option value="">Şehir Seçin</option>
    <option value="istanbul">İstanbul</option>
    <option value="ankara">Ankara</option>
    <option value="izmir">İzmir</option>
</select>
<div id="sehir-bilgi"></div>
javascript
const sehirSelect = document.querySelector('#sehir');
const bilgiDiv = document.querySelector('#sehir-bilgi');

const sehirBilgileri = {
    istanbul: 'İstanbul: Türkiye\'nin en kalabalık şehri, 15+ milyon nüfus',
    ankara: 'Ankara: Türkiye\'nin başkenti, 5+ milyon nüfus',
    izmir: 'İzmir: Ege\'nin incisi, 4+ milyon nüfus'
};

sehirSelect.addEventListener('change', function() {
    const secilenSehir = this.value;
    
    if (secilenSehir && sehirBilgileri[secilenSehir]) {
        bilgiDiv.textContent = sehirBilgileri[secilenSehir];
        bilgiDiv.style.display = 'block';
    } else {
        bilgiDiv.style.display = 'none';
    }
});

Gerçek Hayat Örneği: Dinamik Form

Seçime göre yeni alanlar gösterme:

html
<form id="kayit-form">
    <select id="hesap-turu">
        <option value="">Hesap Türü Seçin</option>
        <option value="bireysel">Bireysel</option>
        <option value="kurumsal">Kurumsal</option>
    </select>
    
    <div id="bireysel-alanlar" style="display: none;">
        <input type="text" placeholder="TC Kimlik No">
        <input type="date" placeholder="Doğum Tarihi">
    </div>
    
    <div id="kurumsal-alanlar" style="display: none;">
        <input type="text" placeholder="Şirket Adı">
        <input type="text" placeholder="Vergi No">
        <input type="text" placeholder="Vergi Dairesi">
    </div>
</form>
javascript
const hesapTuru = document.querySelector('#hesap-turu');
const bireyselAlanlar = document.querySelector('#bireysel-alanlar');
const kurumsalAlanlar = document.querySelector('#kurumsal-alanlar');

hesapTuru.addEventListener('change', function() {
    // Önce hepsini gizle
    bireyselAlanlar.style.display = 'none';
    kurumsalAlanlar.style.display = 'none';
    
    // Seçime göre göster
    if (this.value === 'bireysel') {
        bireyselAlanlar.style.display = 'block';
    } else if (this.value === 'kurumsal') {
        kurumsalAlanlar.style.display = 'block';
    }
});

Gerçek Hayat Örneği: Fiyat Range Slider

html
<div class="fiyat-filtre">
    <label>Maksimum Fiyat: <span id="fiyat-deger">500</span> TL</label>
    <input type="range" id="fiyat-slider" min="0" max="1000" value="500" step="50">
</div>
javascript
const slider = document.querySelector('#fiyat-slider');
const degerSpan = document.querySelector('#fiyat-deger');

// input: Her harekette güncelle (canlı)
slider.addEventListener('input', function() {
    degerSpan.textContent = this.value;
});

// change: Kullanıcı slider'ı bıraktığında API çağır
slider.addEventListener('change', function() {
    console.log('Fiyat filtresi uygulanıyor:', this.value);
    urunleriFiltretle(this.value);
});

input vs change vs keyup Karşılaştırması

EventText InputCheckboxSelectKopyala-Yapıştır
inputHer karakter❌❌✅
changeBlur'daTıklamadaSeçimdeBlur'da
keyupHer tuş❌❌❌ (sadece Ctrl+V)

Neden keyup Yerine input?

javascript
// ❌ keyup - Kopyala-yapıştır'ı yakalar ama eksik
input.addEventListener('keyup', function() {
    console.log(this.value);
});

// ✅ input - Her değişikliği yakalar
input.addEventListener('input', function() {
    console.log(this.value);
});

keyup sadece fiziksel tuş vuruşlarını yakalar. Sağ tık menüsünden yapıştırma, sürükle-bırak gibi işlemleri yakalamaz. Bu yüzden input event'i tercih edilmelidir.

Gerçek Hayat Örneği: E-posta Doğrulama (Canlı)

javascript
const emailInput = document.querySelector('#email');
const durum = document.querySelector('#email-durum');

emailInput.addEventListener('input', function() {
    const email = this.value;
    
    if (email === '') {
        durum.textContent = '';
        return;
    }
    
    // Basit e-posta regex kontrolü
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
    
    if (emailRegex.test(email)) {
        durum.textContent = '✅ Geçerli e-posta';
        durum.style.color = 'green';
        this.classList.remove('gecersiz');
        this.classList.add('gecerli');
    } else {
        durum.textContent = '❌ Geçersiz e-posta formatı';
        durum.style.color = 'red';
        this.classList.remove('gecerli');
        this.classList.add('gecersiz');
    }
});

Özet

Bu makalede öğrendiklerimiz:

✅ input event'i her değişiklikte tetiklenir (canlı takip için ideal)
✅ change event'i input'tan çıkıldığında tetiklenir
✅ Checkbox, radio ve select'te change anında tetiklenir
✅ input, kopyala-yapıştır dahil tüm değişiklikleri yakalar
✅ keyup yerine input tercih edilmelidir

JavaScript Classes ile pratik uygulamalar, metotlar arası iletişim ve gerçek dünya kod örnekleri
JavaScript Dersleri9 dk okuma

JavaScript Classes - Pratik Uygulamalar

JavaScript class'ları ile pratik uygulamalara geçin! Metotlar arası iletişimden constructor'da metot çağırmaya, kod tekrarını azaltmaktan gerçek dünya senaryolarına kadar class kullanımının inceliklerini keşfedin. Kendi alışveriş sepeti örneğinizle bilginizi pekiştirin.

Yazıyı oku
JavaScript class yapısını gösteren bir kod örneği, ES6 ile modern nesne oluşturma
JavaScript Dersleri9 dk okuma

JavaScript Classes

ES6 ile JavaScript'e gelen class yapısı sayesinde nesne oluşturmak artık çok daha kolay ve düzenli! Constructor function karmaşasından kurtulup, okunabilir ve yönetilebilir kodlar yazmak isteyenler için modern JavaScript'in temel taşı olan class'ları tüm detaylarıyla keşfedin. Bu rehberle nesne şabl

Yazıyı oku
JavaScript kodunda Constructor Function ve new keyword'ü ile nesne oluşturma örnekleri
JavaScript Dersleri8 dk okuma

Constructor Functions ve new Keyword

Factory Function'ların hafıza israfı sorununa Constructor Function'lar ve new keyword'ü ile son verin! Metotları paylaştırarak JavaScript objelerini daha verimli nasıl oluşturacağınızı, new'in perde arkasında neler yaptığını ve prototype sisteminin gücünü bu rehberde keşfedin.

Yazıyı oku

Çerez tercihlerin

Platformun çalışması için zorunlu çerezler kullanıyoruz. İzin verirsen anonim kullanım verilerini ölçüyoruz. Ayrıntıları incele