JavaScript Eğitimi #9: Events ve Form İşleme - Kullanıcı Etkileşimlerini Yakalayın
JavaScript event sistemi, addEventListener, form validasyonu ve localStorage kullanımını öğrenin. Kullanıcı etkileşimli web uygulamaları geliştirin.
JavaScript Eğitimi #9: Events ve Form İşleme
Önceki derste DOM manipülasyonunu öğrendik. Elementleri seçebildik, değiştirebildik, oluşturabildik. Ama kullanıcı etkileşimi olmadan bunlar çok da kullanışlı değil. Bu derste event (olay) sistemini öğreneceğiz. Bir butona tıklama, form gönderme, klavye tuşuna basma - tüm bu etkileşimler event'lerle yakalanır.
Event-driven programming (olay güdümlü programlama), modern web geliştirmenin temelidir. Kullanıcı bir şey yapar (event), program tepki verir (handler). Bu yapıyı anlamak, dinamik ve etkileşimli web uygulamaları geliştirmenin anahtarıdır.
İçindekiler
- Event Nedir?
- addEventListener
- Event Nesnesi
- Yaygın Event Türleri
- Event Bubbling ve Capturing
- Event Delegation
- Form İşleme
- Form Validasyonu
- Keyboard Events
- Local Storage
- Pratik Örnekler
- Sık Sorulan Sorular
- Sonuç
Event Nedir?
Event, tarayıcıda gerçekleşen bir eylemdir. Kullanıcı tıklama, klavye tuşuna basma, fare hareketi gibi eylemler yapabilir. Sayfa yüklenme, pencere boyutlandırma gibi sistem eventleri de vardır.
const buton = document.querySelector("#buton");
// Event handler (olay işleyici) ekleme
buton.addEventListener("click", function() {
console.log("Butona tıklandı!");
});Temel Event Akışı
- Kullanıcı bir eylem yapar (örn: tıklama)
- Tarayıcı bir event nesnesi oluşturur
- Event ilgili element'e gönderilir
- Bağlı event handler çalışır
addEventListener
Event dinlemenin modern ve önerilen yöntemi:
element.addEventListener(eventTipi, handlerFonksiyonu, secenekler);Temel Kullanım
const buton = document.querySelector("#buton");
// Anonim fonksiyon
buton.addEventListener("click", function() {
console.log("Tıklandı!");
});
// Arrow function
buton.addEventListener("click", () => {
console.log("Tıklandı!");
});
// İsimli fonksiyon (kaldırmak için gerekli)
function tiklaHandler() {
console.log("Tıklandı!");
}
buton.addEventListener("click", tiklaHandler);
// Event'i kaldırma (aynı fonksiyon referansı gerekli)
buton.removeEventListener("click", tiklaHandler);Birden Fazla Event Listener
const buton = document.querySelector("#buton");
// Aynı event'e birden fazla listener eklenebilir
buton.addEventListener("click", () => console.log("İlk handler"));
buton.addEventListener("click", () => console.log("İkinci handler"));
buton.addEventListener("click", () => console.log("Üçüncü handler"));
// Hepsi sırayla çalışırSeçenekler
// once: true - bir kez çalış, sonra otomatik kaldır
buton.addEventListener("click", () => {
console.log("Bu sadece bir kez çalışır");
}, { once: true });
// capture: true - capturing fazında çalış
buton.addEventListener("click", handler, { capture: true });
// passive: true - preventDefault çağrılmayacağını belirtir (performans)
element.addEventListener("scroll", handler, { passive: true });Eski Yöntem (Önerilmez)
// onclick property - sadece bir handler
buton.onclick = function() {
console.log("Tıklandı");
};
// İkinci atama ilkini ezer
buton.onclick = function() {
console.log("Yeni handler");
};
// inline HTML - en kötü yöntem
// <button onclick="handleClick()">Tıkla</button>Event Nesnesi
Handler fonksiyonuna otomatik olarak event nesnesi geçirilir:
buton.addEventListener("click", function(event) {
// veya kısa adıyla 'e'
console.log(event);
});Önemli Event Özellikleri
element.addEventListener("click", function(e) {
// Event tipi
console.log(e.type); // "click"
// Hedef element (event'in gerçekleştiği)
console.log(e.target);
// Handler'ın bağlı olduğu element
console.log(e.currentTarget);
// Fare koordinatları
console.log(e.clientX, e.clientY); // Viewport'a göre
console.log(e.pageX, e.pageY); // Sayfa'ya göre
// Modifier tuşları
console.log(e.ctrlKey); // Ctrl basılı mı
console.log(e.shiftKey); // Shift basılı mı
console.log(e.altKey); // Alt basılı mı
console.log(e.metaKey); // Cmd/Win basılı mı
// Zaman damgası
console.log(e.timeStamp);
});preventDefault()
Varsayılan davranışı engeller:
// Link tıklamasını engelle
const link = document.querySelector("a");
link.addEventListener("click", function(e) {
e.preventDefault();
console.log("Link'e gidilmedi!");
});
// Form gönderimini engelle
const form = document.querySelector("form");
form.addEventListener("submit", function(e) {
e.preventDefault();
console.log("Form gönderilmedi, JavaScript ile işlenecek");
});
// Sağ tık menüsünü engelle
document.addEventListener("contextmenu", function(e) {
e.preventDefault();
console.log("Sağ tık menüsü engellendi");
});stopPropagation()
Event'in üst elementlere yayılmasını durdurur:
const ic = document.querySelector("#ic");
const dis = document.querySelector("#dis");
dis.addEventListener("click", () => console.log("Dış tıklandı"));
ic.addEventListener("click", (e) => {
e.stopPropagation();
console.log("İç tıklandı");
// Dış'ın handler'ı çalışmaz
});Yaygın Event Türleri
Mouse Events
const element = document.querySelector("#element");
// Tıklama
element.addEventListener("click", () => console.log("Tek tık"));
element.addEventListener("dblclick", () => console.log("Çift tık"));
// Fare tuşları
element.addEventListener("mousedown", () => console.log("Tuş basıldı"));
element.addEventListener("mouseup", () => console.log("Tuş bırakıldı"));
// Fare hareketi
element.addEventListener("mousemove", (e) => {
console.log(`Koordinat: ${e.clientX}, ${e.clientY}`);
});
// Giriş/çıkış
element.addEventListener("mouseenter", () => console.log("Üzerine gelindi"));
element.addEventListener("mouseleave", () => console.log("Üzerinden çıkıldı"));
// Hover (bubbling ile)
element.addEventListener("mouseover", () => console.log("Üzerinde"));
element.addEventListener("mouseout", () => console.log("Dışında"));Keyboard Events
// Herhangi bir tuşa basıldığında
document.addEventListener("keydown", (e) => {
console.log("Tuş basıldı:", e.key);
console.log("Kod:", e.code);
});
// Tuş bırakıldığında
document.addEventListener("keyup", (e) => {
console.log("Tuş bırakıldı:", e.key);
});
// Özel tuş kombinasyonları
document.addEventListener("keydown", (e) => {
// Ctrl + S
if (e.ctrlKey && e.key === "s") {
e.preventDefault();
console.log("Kaydet!");
}
// Escape
if (e.key === "Escape") {
console.log("İptal");
}
// Enter
if (e.key === "Enter") {
console.log("Gönder");
}
});Focus Events
const input = document.querySelector("input");
// Focus aldığında
input.addEventListener("focus", () => {
console.log("Input aktif");
input.style.borderColor = "blue";
});
// Focus kaybettiğinde
input.addEventListener("blur", () => {
console.log("Input pasif");
input.style.borderColor = "";
});
// Focus geçişleri (bubbling ile)
document.addEventListener("focusin", (e) => {
console.log("Focus aldı:", e.target);
});
document.addEventListener("focusout", (e) => {
console.log("Focus kaybetti:", e.target);
});Input Events
const input = document.querySelector("input");
// Her değişiklikte (gerçek zamanlı)
input.addEventListener("input", (e) => {
console.log("Değer:", e.target.value);
});
// Değişiklik tamamlandığında (blur sonrası)
input.addEventListener("change", (e) => {
console.log("Değişti:", e.target.value);
});Window Events
// Sayfa yüklendiğinde
window.addEventListener("load", () => {
console.log("Sayfa ve tüm kaynaklar yüklendi");
});
// DOM hazır olduğunda (daha erken)
document.addEventListener("DOMContentLoaded", () => {
console.log("DOM hazır");
});
// Pencere boyutu değiştiğinde
window.addEventListener("resize", () => {
console.log(`Boyut: ${window.innerWidth}x${window.innerHeight}`);
});
// Scroll
window.addEventListener("scroll", () => {
console.log(`Scroll: ${window.scrollY}`);
});
// Sayfa kapatılmadan önce
window.addEventListener("beforeunload", (e) => {
e.preventDefault();
e.returnValue = "";
// Tarayıcı kullanıcıya onay sorar
});Event Bubbling ve Capturing
Event'ler DOM ağacında iki fazda hareket eder:
- Capturing (yakalama): Üstten alta, document'tan hedefe
- Bubbling (kabarcıklanma): Alttan üste, hedeften document'a
<div id="buyuk">
<div id="orta">
<div id="kucuk">Tıkla</div>
</div>
</div>const buyuk = document.querySelector("#buyuk");
const orta = document.querySelector("#orta");
const kucuk = document.querySelector("#kucuk");
// Varsayılan: Bubbling fazında çalışır
buyuk.addEventListener("click", () => console.log("Büyük"));
orta.addEventListener("click", () => console.log("Orta"));
kucuk.addEventListener("click", () => console.log("Küçük"));
// Küçük'e tıklayınca çıktı:
// Küçük
// Orta
// Büyük
// Capturing fazında çalıştırmak için
buyuk.addEventListener("click", () => console.log("Büyük (capture)"), true);
// veya
buyuk.addEventListener("click", () => console.log("Büyük (capture)"), { capture: true });Event Delegation
Event'i üst elemente bağlayıp, hedefi kontrol etme. Dinamik elementler için çok kullanışlı:
<ul id="liste">
<li>Öğe 1</li>
<li>Öğe 2</li>
<li>Öğe 3</li>
</ul>// Kötü: Her li'ye ayrı event listener
document.querySelectorAll("#liste li").forEach(li => {
li.addEventListener("click", () => {
console.log(li.textContent);
});
});
// İyi: Event delegation
const liste = document.querySelector("#liste");
liste.addEventListener("click", (e) => {
// Sadece li elementlerine tepki ver
if (e.target.tagName === "LI") {
console.log(e.target.textContent);
}
});
// Dinamik eklenen elementler de çalışır
const yeniLi = document.createElement("li");
yeniLi.textContent = "Öğe 4";
liste.appendChild(yeniLi);
// Yeni li'ye tıklayınca da çalışır!closest() ile Delegation
<ul id="liste">
<li>
<span>Metin</span>
<button class="sil">Sil</button>
</li>
</ul>liste.addEventListener("click", (e) => {
// En yakın .sil butonunu bul
const silBtn = e.target.closest(".sil");
if (silBtn) {
// En yakın li'yi bul ve sil
const li = silBtn.closest("li");
li.remove();
}
});Form İşleme
Form Verilerine Erişim
<form id="kayitForm">
<input type="text" name="isim" id="isim">
<input type="email" name="email" id="email">
<input type="password" name="sifre" id="sifre">
<select name="sehir">
<option value="ist">İstanbul</option>
<option value="ank">Ankara</option>
</select>
<input type="checkbox" name="sozlesme" id="sozlesme">
<button type="submit">Kayıt Ol</button>
</form>const form = document.querySelector("#kayitForm");
form.addEventListener("submit", (e) => {
e.preventDefault();
// Tek tek erişim
const isim = document.querySelector("#isim").value;
const email = form.elements.email.value;
const sifre = form.elements["sifre"].value;
const sehir = form.elements.sehir.value;
const sozlesme = form.elements.sozlesme.checked;
console.log({ isim, email, sifre, sehir, sozlesme });
// FormData ile toplu erişim
const formData = new FormData(form);
// FormData'dan nesne oluştur
const veriler = Object.fromEntries(formData);
console.log(veriler);
// FormData'yı döngüyle
for (const [anahtar, deger] of formData) {
console.log(`${anahtar}: ${deger}`);
}
});FormData API
const form = document.querySelector("form");
const formData = new FormData(form);
// Değer okuma
console.log(formData.get("isim"));
console.log(formData.getAll("hobiler")); // Çoklu değerler için
// Değer ekleme/değiştirme
formData.set("yeniAlan", "değer");
formData.append("hobiler", "yeniHobi");
// Silme
formData.delete("gereksizAlan");
// Varlık kontrolü
console.log(formData.has("isim")); // true
// JSON'a çevirme
const jsonData = JSON.stringify(Object.fromEntries(formData));
// Fetch ile gönderme
fetch("/api/kayit", {
method: "POST",
body: formData
});Form Validasyonu
HTML5 Validasyon
<form id="form">
<input type="text" name="isim" required minlength="2" maxlength="50">
<input type="email" name="email" required>
<input type="password" name="sifre" required minlength="8" pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{8,}">
<input type="tel" name="telefon" pattern="[0-9]{10}">
<input type="number" name="yas" min="18" max="120">
<input type="url" name="website">
<button type="submit">Gönder</button>
</form>JavaScript Validasyonu
const form = document.querySelector("#form");
form.addEventListener("submit", (e) => {
e.preventDefault();
const hatalar = [];
const formData = new FormData(form);
// İsim validasyonu
const isim = formData.get("isim").trim();
if (!isim) {
hatalar.push("İsim gereklidir");
} else if (isim.length < 2) {
hatalar.push("İsim en az 2 karakter olmalıdır");
}
// Email validasyonu
const email = formData.get("email").trim();
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!email) {
hatalar.push("Email gereklidir");
} else if (!emailRegex.test(email)) {
hatalar.push("Geçerli bir email adresi girin");
}
// Şifre validasyonu
const sifre = formData.get("sifre");
if (!sifre) {
hatalar.push("Şifre gereklidir");
} else if (sifre.length < 8) {
hatalar.push("Şifre en az 8 karakter olmalıdır");
} else if (!/[A-Z]/.test(sifre)) {
hatalar.push("Şifre en az bir büyük harf içermelidir");
} else if (!/[0-9]/.test(sifre)) {
hatalar.push("Şifre en az bir rakam içermelidir");
}
// Hata varsa göster
if (hatalar.length > 0) {
alert(hatalar.join("\n"));
return;
}
// Form geçerli, gönder
console.log("Form gönderiliyor...");
});Gerçek Zamanlı Validasyon
const emailInput = document.querySelector("#email");
const emailHata = document.querySelector("#emailHata");
emailInput.addEventListener("input", (e) => {
const email = e.target.value;
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (email && !emailRegex.test(email)) {
emailInput.classList.add("hatali");
emailHata.textContent = "Geçerli email girin";
} else {
emailInput.classList.remove("hatali");
emailHata.textContent = "";
}
});
// Blur'da detaylı kontrol
emailInput.addEventListener("blur", async (e) => {
const email = e.target.value;
if (!email) return;
// API ile email kontrolü (örnek)
// const exists = await checkEmailExists(email);
// if (exists) {
// emailHata.textContent = "Bu email zaten kayıtlı";
// }
});Keyboard Events
Klavye Kontrolleri
// Arama kutusu - Enter ile arama
const aramaInput = document.querySelector("#arama");
aramaInput.addEventListener("keydown", (e) => {
if (e.key === "Enter") {
e.preventDefault();
aramaYap(aramaInput.value);
}
});
// Modal kapatma - ESC tuşu
document.addEventListener("keydown", (e) => {
if (e.key === "Escape") {
modalKapat();
}
});
// Kısayol tuşları
document.addEventListener("keydown", (e) => {
// Ctrl/Cmd + K - Arama aç
if ((e.ctrlKey || e.metaKey) && e.key === "k") {
e.preventDefault();
aramaModalAc();
}
// Ctrl/Cmd + S - Kaydet
if ((e.ctrlKey || e.metaKey) && e.key === "s") {
e.preventDefault();
kaydet();
}
// Ctrl/Cmd + Z - Geri al
if ((e.ctrlKey || e.metaKey) && e.key === "z") {
if (e.shiftKey) {
ileriAl();
} else {
geriAl();
}
}
});key vs code
document.addEventListener("keydown", (e) => {
console.log("key:", e.key); // Karakter: "a", "A", "Enter", "Escape"
console.log("code:", e.code); // Fiziksel tuş: "KeyA", "Enter", "Escape"
// Oyun kontrolleri için code kullan (klavye düzeninden bağımsız)
if (e.code === "KeyW") console.log("Yukarı");
if (e.code === "KeyS") console.log("Aşağı");
if (e.code === "KeyA") console.log("Sol");
if (e.code === "KeyD") console.log("Sağ");
if (e.code === "Space") {
e.preventDefault();
console.log("Zıpla");
}
});Local Storage
Tarayıcıda veri saklama:
Temel Kullanım
// Kaydetme
localStorage.setItem("isim", "Ali");
localStorage.setItem("yas", "25");
// Okuma
const isim = localStorage.getItem("isim"); // "Ali"
const yas = localStorage.getItem("yas"); // "25" (string!)
// Silme
localStorage.removeItem("yas");
// Tümünü silme
localStorage.clear();
// Anahtar sayısı
console.log(localStorage.length);
// Index ile anahtar alma
console.log(localStorage.key(0));Nesne Saklama
// Nesne saklama (JSON.stringify)
const kullanici = {
isim: "Ali",
yas: 25,
tercihler: {
tema: "karanlik",
dil: "tr"
}
};
localStorage.setItem("kullanici", JSON.stringify(kullanici));
// Nesne okuma (JSON.parse)
const kayitli = localStorage.getItem("kullanici");
const okunanKullanici = kayitli ? JSON.parse(kayitli) : null;
console.log(okunanKullanici.tercihler.tema);LocalStorage Helper
const storage = {
get(key, varsayilan = null) {
const veri = localStorage.getItem(key);
if (!veri) return varsayilan;
try {
return JSON.parse(veri);
} catch {
return veri;
}
},
set(key, deger) {
const veri = typeof deger === "string" ? deger : JSON.stringify(deger);
localStorage.setItem(key, veri);
},
remove(key) {
localStorage.removeItem(key);
},
clear() {
localStorage.clear();
}
};
// Kullanım
storage.set("ayarlar", { tema: "dark", dil: "tr" });
const ayarlar = storage.get("ayarlar", { tema: "light" });Session Storage
localStorage gibi ama sekme kapanınca silinir:
// Aynı API
sessionStorage.setItem("geciciVeri", "değer");
const veri = sessionStorage.getItem("geciciVeri");
sessionStorage.removeItem("geciciVeri");
sessionStorage.clear();Storage Event
Başka sekmelerden değişiklikleri dinleme:
window.addEventListener("storage", (e) => {
console.log("Anahtar:", e.key);
console.log("Eski değer:", e.oldValue);
console.log("Yeni değer:", e.newValue);
console.log("URL:", e.url);
// Örnek: Çıkış yapıldığında tüm sekmeleri güncelle
if (e.key === "kullanici" && e.newValue === null) {
location.href = "/giris";
}
});Pratik Örnekler
Örnek 1: Karakter Sayacı
<textarea id="mesaj" maxlength="200" placeholder="Mesajınız..."></textarea>
<div id="sayac">0/200</div>const mesaj = document.querySelector("#mesaj");
const sayac = document.querySelector("#sayac");
const maxKarakter = mesaj.maxLength;
mesaj.addEventListener("input", (e) => {
const mevcutUzunluk = e.target.value.length;
sayac.textContent = `${mevcutUzunluk}/${maxKarakter}`;
// Uyarı rengi
if (mevcutUzunluk > maxKarakter * 0.9) {
sayac.style.color = "red";
} else if (mevcutUzunluk > maxKarakter * 0.7) {
sayac.style.color = "orange";
} else {
sayac.style.color = "";
}
});Örnek 2: Debounced Arama
function debounce(fn, delay) {
let timeoutId;
return function(...args) {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => fn.apply(this, args), delay);
};
}
const aramaInput = document.querySelector("#arama");
const sonuclar = document.querySelector("#sonuclar");
const aramaYap = debounce(async (sorgu) => {
if (sorgu.length < 2) {
sonuclar.innerHTML = "";
return;
}
sonuclar.innerHTML = "Aranıyor...";
try {
// API çağrısı simülasyonu
const response = await fetch(`/api/arama?q=${encodeURIComponent(sorgu)}`);
const data = await response.json();
sonuclar.innerHTML = data.length
? data.map(item => `<div class="sonuc">${item.baslik}</div>`).join("")
: "Sonuç bulunamadı";
} catch (error) {
sonuclar.innerHTML = "Hata oluştu";
}
}, 300);
aramaInput.addEventListener("input", (e) => {
aramaYap(e.target.value.trim());
});Örnek 3: Form Kaydetme
const form = document.querySelector("#form");
const STORAGE_KEY = "formTaslak";
// Sayfa yüklendiğinde kaydedilmiş veriyi yükle
document.addEventListener("DOMContentLoaded", () => {
const kaydedilmis = storage.get(STORAGE_KEY);
if (kaydedilmis) {
Object.entries(kaydedilmis).forEach(([name, value]) => {
const input = form.elements[name];
if (input) {
if (input.type === "checkbox") {
input.checked = value;
} else {
input.value = value;
}
}
});
}
});
// Her değişiklikte kaydet
form.addEventListener("input", () => {
const formData = new FormData(form);
const veri = {};
for (const [key, value] of formData) {
veri[key] = value;
}
// Checkbox'ları da ekle
form.querySelectorAll('input[type="checkbox"]').forEach(cb => {
veri[cb.name] = cb.checked;
});
storage.set(STORAGE_KEY, veri);
});
// Form gönderildiğinde taslağı sil
form.addEventListener("submit", (e) => {
e.preventDefault();
// ... form gönderme işlemi
storage.remove(STORAGE_KEY);
});Örnek 4: Sonsuz Scroll
const icerikContainer = document.querySelector("#icerik");
let sayfa = 1;
let yukleniyor = false;
async function veriYukle() {
if (yukleniyor) return;
yukleniyor = true;
const yukleniyorEl = document.createElement("div");
yukleniyorEl.className = "yukleniyor";
yukleniyorEl.textContent = "Yükleniyor...";
icerikContainer.appendChild(yukleniyorEl);
try {
const response = await fetch(`/api/veriler?sayfa=${sayfa}`);
const veriler = await response.json();
yukleniyorEl.remove();
if (veriler.length === 0) {
// Daha fazla veri yok
window.removeEventListener("scroll", scrollHandler);
return;
}
veriler.forEach(item => {
const el = document.createElement("div");
el.className = "item";
el.innerHTML = `<h3>${item.baslik}</h3><p>${item.icerik}</p>`;
icerikContainer.appendChild(el);
});
sayfa++;
} catch (error) {
yukleniyorEl.textContent = "Hata oluştu";
} finally {
yukleniyor = false;
}
}
function scrollHandler() {
const { scrollTop, scrollHeight, clientHeight } = document.documentElement;
// Sayfanın %80'ine ulaşıldığında yükle
if (scrollTop + clientHeight >= scrollHeight * 0.8) {
veriYukle();
}
}
window.addEventListener("scroll", scrollHandler);
veriYukle(); // İlk yüklemeSık Sorulan Sorular
onclick mi addEventListener mi?
addEventListener tercih edilir. Birden fazla handler ekleyebilir, capture/bubble kontrolü yapabilir ve removeEventListener ile kaldırabilirsiniz.
e.target ve e.currentTarget farkı?
e.target event'in gerçekleştiği element, e.currentTarget handler'ın bağlı olduğu element. Event delegation'da bu fark önemli.
localStorage'da ne kadar veri saklayabilirim?
Genellikle 5-10MB arası. Tarayıcıya göre değişir. Büyük veriler için IndexedDB tercih edilir.
Event handler içinde async/await kullanabilir miyim?
Evet, handler'ı async yapabilirsiniz. Ama hata yönetimini (try/catch) unutmayın.
Sayfa kapanırken veri kaybını nasıl önlerim?
beforeunload event'i ile uyarı gösterebilir, visibilitychange ile sekme değişiminde otomatik kaydedebilirsiniz.
Sonuç
Bu derste JavaScript event sistemini kapsamlı şekilde öğrendik. addEventListener ile event dinlemeyi, event nesnesi ve metodlarını gördük. Event bubbling, delegation ve form işlemeyi inceledik. localStorage ile veri kalıcılığını öğrendik.
Event-driven programming modern web'in temelidir. Kullanıcı etkileşimli her uygulama bu yapı üzerine kurulur. React, Vue gibi frameworkler de arka planda event sistemini kullanır.
Pratik için:
- Form validasyonlu kayıt sayfası yapın
- Sürükle-bırak özelliği ekleyin
- Klavye kısayolları olan not defteri yapın
- Otomatik kaydeden metin editörü oluşturun
Sonraki Ders
Bir sonraki ve son derste Proje: Todo Uygulaması yapacağız. Bu seride öğrendiğimiz tüm konuları birleştirerek tam fonksiyonlu bir uygulama geliştireceğiz.
JavaScript Eğitimi #10: Proje - Todo Uygulaması →
Kaynaklar
Projenizi Hayata Geçirelim
Web sitesi, mobil uygulama veya yapay zeka çözümü mü arıyorsunuz? Fikirlerinizi birlikte değerlendirelim.
Ücretsiz Danışmanlık Alın