Kısım II · İnşaat · Bölüm 26
JavaScript ile Sayfayı Canlandırmak
Belge, kullanıcı eylemi ve durumun buluşması (DOM manipulation and events)
Neden burada: HTML belgeyi, CSS sunumu, JavaScript dilin kurallarını verdi. Bu bölüm onları bir cevap eyleminde birleştiriyor: kullanıcı şık seçince hangi kod çalışır, hangi veri değişir, hangi DOM düğümü güncellenir?
Neye dayanıyor: Bölüm 23: belge ağacı, form ve girdi grupları; Bölüm 24: seçiciler, sınıflar ve sunumun ayrı tutulması; Bölüm 25: fonksiyon, nesne, kapsam, Promise ve hata yolları.
- Kat 10Bizim uygulamamızSorular, puan, günlük seri ve can kuralları.
- Kat 9Web ve tarayıcıHTML belgeyi, CSS sunumu, JavaScript davranışı kurar; bu bölümün çalışma alanı.
- Kat 7–8İşletim sistemi ve ağDosyaları, süreçleri ve veri alışverişini sağlar; belge bunların üstünde çalışır.
- Kat 0–6Bitten işlemciye, belleğe ve dillereÖnceki bölümlerde kurduğumuz temel. Tam kat planı.
Bölüm sonunda olay–durum–ekran yolunu, tarayıcı kaydını ve fetch hata sınırlarını açıklayabileceksin.
26.1 DOM API: seçmek, oluşturmak, metni değiştirmek
23.5 kaynak ile DOM’u, 25 dili kurdu. DOM API (Document Object Model API), programın belgeyi okuyup değiştirmesi için sunulan sözleşmedir. Bu, uzak Go sunucusuna HTTP isteği değil, tarayıcıdaki belge nesneleriyle çalışmaktır.1
const puanYazisi = document.querySelector("#puan");
if (puanYazisi !== null) {
puanYazisi.textContent = "10";
}
document geçerli belgedir. İlk satır 24.1’deki kimlik seçicisiyle ilk eşleşmeyi alır; yoksa null döner. Koşul bunu denetler; içteki atama metni değiştirir, kapanış bloğu bitirir. Kaynak dosya değil canlı belge değişir.23
querySelectorAll bütün eşleşmeleri diziye benzeyen NodeList koleksiyonunda verir. null aldıysan seçiciyi ve çalışma anını ayır: öğe yok mu, henüz kurulmadı mı? 23.2’deki dış klasik betikte defer, ikinci sorunu önlemek içindir.12
const kap = document.querySelector("#siklar");
const dugme = document.createElement("button");
dugme.type = "button";
dugme.textContent = "Genel ifade";
kap.appendChild(dugme);
Bu küçük örnek, belgede siklar kimlikli kapsayıcı bulunduğunu varsayar. İlk satır onu bulur. İkinci satır yeni bir düğme nesnesi oluşturur; düğme henüz belge ağacına bağlanmadığı için ekranda görünmez. Sonraki iki satır düğmenin türünü ve yazısını ayarlar. Son satır onu kapsayıcının çocuğu yapar. “Oluşturmak” ve “belgeye eklemek” iki ayrı adımdır. Asıl çoktan seçmeli kartımızda serbest düğmeler yerine önceki bölümdeki tek seçim girdilerini ve formu kullanacağız; burada yalnızca oluşturma–ekleme sınırını görüyoruz.1
Metin yazmak ile HTML yorumlatmak aynı şey değil
textContent ile "<strong>Doğru</strong>" atarsan bu bir işaretleme komutu olarak değil, metin olarak kullanılır. Buna karşılık innerHTML, verilen metni HTML olarak ayrıştırır. Kullanıcıdan veya dış veriden gelen soru metnini ham HTML diye yorumlatmak tehlikeli olabilir. Bu bölümde soru ve şık yazıları için textContent veya metin düğümü kullanacağız; güvenlik ayrıntıları Bölüm 41'de gelecek.3
textContent atamak çocukları kaldırır. İstatistik paragrafının tümüne sayı yazarsan etiketi ve içteki strong da gider; yalnız sayıya ayrılan span’i değiştir. Şık kabını temizlemek istediğimizde aynı davranışı bilerek kullanacağız.3
classList.add, remove ve toggle sınıfları değiştirir; görünüm CSS’te kalabilir. Fakat dogru sınıfı eklemek doğruluk hesaplaması değildir: önce sonucu belirleriz.4
26.2 Olaylar: click, input, submit ve olay dinleyici
Şimdiye kadar kodu baştan sona çalıştırdık. Kullanıcı cevabı ne zaman verecek bilmiyoruz; programın sonsuz bir döngüyle sürekli fareyi kontrol etmesini de istemiyoruz. Olay (event), ortamda gerçekleşen ve programın tepki verebildiği bir bildirimdir. Olay dinleyici (event listener), belirli olay için kaydedilen tepkidir. Kullanıcının eylemi olduğunda tarayıcı uygun fonksiyonu çağırır. Bölüm 25.6'daki geri çağırma, bu kez kullanıcı girdisine bağlanır.5
const sonraki = document.querySelector("#sonraki");
sonraki.addEventListener("click", () => {
console.log("Sonraki soruya geçme isteği geldi.");
});
İlk satır düğmeyi bulur. İkinci satır click için fonksiyon kaydeder; içteki mesaj şimdi değil olay olduğunda yazılır. Son satır gövdeyi ve çağrıyı kapatır. Bu örnek yalnızca bildirim yazar. Gerçek bir düğme klavyeyle de etkinleştirilebilir; click yalnızca fare demek değildir.56
| Olay | Bu kartta neyi dinleriz? | Neyi karıştırmayız? |
|---|---|---|
click | Sonraki soru düğmesinin etkinleştirilmesini | Bir formun bütün gönderilme yollarını yalnızca bu düğmeye indirgemeyiz. |
input | Kullanıcının girdi değerini değiştirmesini | Programın value atamasının kendiliğinden aynı olayı ürettiğini varsaymayız. |
submit | Formun gönderme girişimini | Bu olayı şık girdisinde değil formun kendisinde karşılarız. |
input kullanıcı düzenlemesini bildirir. Yerleşik doğrulamadan geçemeyen formda submit oluşmayabilir; required yüzünden seçimsiz gönderimin durması JavaScript hatası değildir.78
const form = document.querySelector("#cevap-formu");
form.addEventListener("submit", (olay) => {
olay.preventDefault();
console.log("Cevap yerel olarak değerlendirilecek.");
});
İlk satır formu seçer. İkincisi olay nesnesi (event object) alan fonksiyonu kaydeder. preventDefault varsayılan gönderimi durdurur; sonraki satır mesaj yazar. Bu işlem alanları silmez veya olay yayılmasını kesmez.58
Olay ağacın içinde ilerleyebilir
Birçok olay hedeften üst öğelere kabarcıklanma (event bubbling) yoluyla yayılır. target ilk hedef, currentTarget çalışan dinleyicinin bağlı olduğu öğedir. Olay devretme (event delegation), çocuk olayını ortak ebeveynde karşılayarak bundan yararlanır. Her olay aynı şekilde yayılmaz.9
Aşağıda formun input dinleyicisini bir kez kuracağız. Yeni kartta tekrar dinleyici eklemiyoruz: ekran güncelleyen fonksiyon her çalıştığında yeni işleyici kaydetmek, tek eyleme birden çok tepki bağlayabilir. Dinleyici kurma ile görünümü güncelleme bu yüzden ayrı.59
26.3 Durum ve ekranı güncellemek: puan, seri, soru ilerleyişi
Durum (state), sonraki davranışı belirleyen hatırlanmış veridir. Ekran bunun çıktısı olabilir. Bu örnekte puanı DOM’dan okumak yerine nesnede tutacağız: olay → denetle → durumu değiştir → ekranı güncelle. Bu, nesne ve DOM imkânlarıyla kurduğumuz tasarım; otomatik tarayıcı kuralı değil.110
Aşağıdaki örnek gerçek prototipinin kopyası değil. İki yapay soru, her doğruya 10 puan, yanlışta bir can eksilmesi, her sorunun yalnızca bir kez değerlendirilmesi ve açık bir sonraki soru eylemi var. Seri günlük seridir; başlangıçta gösterilen 7 örnek veridir ve bu kod onu artırmaz. Gün tamamlandı mı, hangi saat dilimindeyiz gibi kurallar sonraki katların konusudur. Giriş, kullanıcı hesabı, ortak sıralama veya sunucu doğrulaması yoktur.
Deneme için üç ayrı dosya kullan: index.html, style.css, script.js. CSS’e 24’teki kutu ve şık kurallarını al; stiller olmasa da yerleşik HTML denetimleri çalışır.16
<!doctype html>
<html lang="tr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>İki kartlık alıştırma</title>
<link rel="stylesheet" href="style.css">
<script src="script.js" defer></script>
</head>
<body>
<main class="calisma">
<h1>Hukuka Giriş · Deneme</h1>
<p>Puan: <span id="puan">0</span>
· Günlük seri: <span id="seri">7</span>
· Can: <span id="can">3</span></p>
<section class="soru-karti" aria-labelledby="soru-basligi">
<h2 id="soru-basligi">Soru</h2>
<form id="cevap-formu">
<fieldset id="secim-alani">
<legend id="soru-metni">Soru hazırlanıyor.</legend>
<div id="siklar" class="siklar"></div>
</fieldset>
<button id="kontrol" type="submit">Cevabı kontrol et</button>
</form>
<button id="sonraki" type="button" disabled>Sonraki soru</button>
<p id="sonuc" role="status"></p>
</section>
</main>
</body>
</html>
head satırları 23.2’deki kodlama, görünüm alanı ve kaynak bağlantılarıdır; defer betiği ayrıştırma sonrasına bırakır. Üç span sayı çıktılarıdır. Kart başlığıyla adlandırılır; formda alan grubu, soru açıklaması, boş şık kabı ve gönderme düğmesi bulunur. Form dışındaki sonraki düğmesi başta kapalıdır. status paragrafı geri bildirimi taşır; kapanışlar yapıyı tamamlar.611
Birinci parça: veri ve belgeye açılan kapılar
const sorular = [
{ metin: "Bu örnekte kural etiketi hangi şıkla eşleşiyor?",
siklar: ["Genel ifade", "Tekil olay"], dogruIndeks: 0 },
{ metin: "Bu örnekte olay etiketi hangi şıkla eşleşiyor?",
siklar: ["Genel ifade", "Tekil olay"], dogruIndeks: 1 }
];
const durum = { sira: 0, puan: 0, can: 3, seri: 7, cevaplandi: false };
const form = document.querySelector("#cevap-formu");
const alan = document.querySelector("#secim-alani");
const baslik = document.querySelector("#soru-basligi");
const metin = document.querySelector("#soru-metni");
const siklar = document.querySelector("#siklar");
const kontrol = document.querySelector("#kontrol");
const sonraki = document.querySelector("#sonraki");
const sonuc = document.querySelector("#sonuc");
İlk altı satır iki soru nesnesidir. Durumda sira indeks, cevaplandi tekrar değerlendirme bayrağıdır. Kalan satırların her biri adı yazılı kimliğin DOM referansını alır. Kod yukarıdaki HTML’e bağlıdır; kimlik uyuşmazsa null gelebilir ve geliştirme hatası görünür olur.210
İkinci parça: durumdan çıktıya
function sayilariGoster() {
document.querySelector("#puan").textContent = String(durum.puan);
document.querySelector("#can").textContent = String(durum.can);
document.querySelector("#seri").textContent = String(durum.seri);
}
function kartiKur() {
sayilariGoster();
const bitti = durum.sira >= sorular.length || durum.can === 0;
alan.disabled = bitti;
kontrol.disabled = bitti;
sonraki.disabled = true;
if (bitti) {
baslik.textContent = "Alıştırma bitti";
sonuc.textContent = `Toplam puan: ${durum.puan}. Kalan can: ${durum.can}.`;
return;
}
const soru = sorular[durum.sira];
baslik.textContent = `Soru ${durum.sira + 1} / ${sorular.length}`;
metin.textContent = soru.metin;
siklar.textContent = "";
sonuc.textContent = "";
for (let i = 0; i < soru.siklar.length; i = i + 1) {
const etiket = document.createElement("label");
etiket.classList.add("sik");
const girdi = document.createElement("input");
girdi.type = "radio";
girdi.name = "cevap";
girdi.value = String(i);
girdi.required = true;
etiket.appendChild(girdi);
etiket.appendChild(document.createTextNode(soru.siklar[i]));
siklar.appendChild(etiket);
}
}
sayilariGoster'in üç iç satırı sayısal durumu karakter dizisine çevirip ilgili çıktı düğümüne yazar. kartiKur önce bu görünümü eşitler. bitti koşulu soru sınırına gelinmesini veya canın sıfırlanmasını kontrol eder; sonraki üç atama denetimlerin kullanımını düzenler. Bitmişse başlık ve sonuç değiştirilir, return ile çıkılır; böylece dizi sınırının dışından soru okunmaz. Ters tırnaklı karakter dizilerindeki ${…}, hesaplanan değeri metne yerleştiren JavaScript yazımıdır.110
Bitmediyse mevcut soru alınır, başlıkta kullanıcı için indeksin bir fazlası gösterilir ve soru yazısı atanır. Şık kapsayıcısına boş metin atanması önceki çocukları temizler; sonuç da yeni kart için silinir. for sıfırdan başlar, şık sayısına kadar ilerler ve her turda indeksi artırır. Gövdede önce label, sonra input oluşturulur. Sınıf CSS'e, type denetim biçimine, ortak name gruba, value indeksin metin biçimine karşılık gelir. required seçim gerektirir. Son üç ekleme sırasıyla girdiyi etikete, şık yazısının metin düğümünü etikete, etiketi belgeye bağlar; kapanışlar döngü ve fonksiyonu bitirir.1346
Üçüncü parça: olaydan kontrollü durum geçişine
form.addEventListener("input", () => {
if (!durum.cevaplandi) sonuc.textContent = "Seçimin alındı; kontrol edebilirsin.";
});
form.addEventListener("submit", (olay) => {
olay.preventDefault();
if (durum.cevaplandi || durum.can === 0 || durum.sira >= sorular.length) return;
const secilen = form.querySelector('input[name="cevap"]:checked');
if (secilen === null) return;
const dogruMu = Number(secilen.value) === sorular[durum.sira].dogruIndeks;
durum.cevaplandi = true;
if (dogruMu) durum.puan = durum.puan + 10;
else durum.can = durum.can - 1;
sayilariGoster();
sonuc.textContent = dogruMu ? "Doğru cevap. 10 puan eklendi." : "Yanlış cevap. Bir can azaldı.";
alan.disabled = true;
kontrol.disabled = true;
sonraki.disabled = durum.can === 0;
if (durum.can === 0) sonuc.textContent += " Can bitti; alıştırma durdu.";
});
sonraki.addEventListener("click", () => {
if (!durum.cevaplandi || durum.can === 0 || durum.sira >= sorular.length) return;
durum.sira = durum.sira + 1;
durum.cevaplandi = false;
kartiKur();
});
kartiKur();
İlk dinleyici, kullanıcı seçimini gönderme kararıyla karıştırmadan haber verir. İkinci dinleyici form gönderimini yerel karşılar. İlk koruma satırı, daha önce değerlendirilmiş veya bitmiş durumda çalışmayı keser. Seçili girdiyi arayan :checked, işaretli denetimi seçen CSS sözde sınıfıdır; ek null kontrolü de seçimsiz programatik girişimi durdurur. value metin olduğundan Number ile sayıya çevrilir ve doğru indeksle karşılaştırılır. Bu dönüşüm, 25.1'de gördüğün tip sınırıdır.2610
cevaplandi bayrağı puan vermeden önce kapanır. Sonraki iki dal ya puan artırır ya can azaltır; sayılar güncellenir. ? ve : ile yazılan koşullu ifade, doğru veya yanlış mesajından birini seçer. Alan grubu ve kontrol düğmesi kapatılır; böylece kullanıcı aynı kartın cevabını değiştirip tekrar değerlendiremez. Sonraki düğmesi can varsa açık kalır; can yoksa sonuç metni tamamlanır. Bu son atamalar görünümdeki geri bildirimdir; aynı cevabı tekrar işleme yasağının asıl yerel denetimi baştaki korumadır.5610
Son dinleyici yalnızca cevaplanmış karttan ilerler; indeksi bir artırır, yeni soru için bayrağı sıfırlar ve kartı kurar. Yeni indekste dizi bitmişse kartiKur güvenle tamamlanma dalına gider. En alttaki bağımsız çağrı ilk kartı kurar; dinleyicilerin içindeki fonksiyonlar ise sonraki kullanıcı eylemlerinde çalışır. Günlük seri hiçbir satırda artırılmaz. Bu örnekte cevaplar doğru–yanlış olursa sonuç puan 10, can 2, seri 7'dir; iki doğru cevapta puan 20 olur. Hesaplar Python ile doğrulandı; gerçek kullanıcı puanı için sunucu denetimi henüz yoktur.
disabled kullanıcıya izin verilen adımı gösterir; bir saldırganın kendi tarayıcısını değiştirmesini engellemez. Yukarıdaki bayrak, yanlışlıkla çift puanı önleyen yerel bir tasarım kararıdır. Ortak sıralama ve kullanıcı hesaplarında “bu cevap daha önce işlendi mi?” kontrolünün güvenilir sunucuda da yapılması gerekir; Bölüm 22.4'teki sınır değişmedi. Yerel modeli kurduk diye üretim güvenliğini tamamlamış sayılmayız.
26.4 Tarayıcıda saklama: localStorage ve çereze ilk bakış
Şimdi sayfayı yenilediğini düşün: yukarıdaki betik yeniden başlar, durum nesnesi başlangıç değerleriyle kurulur. Bellekteki durumu yaşatmak ile kalıcı bir temsil saklamak farklı işlerdir. Yerel saklama (localStorage), tarayıcıda anahtar–değer çiftleri tutan ve oturumlar arasında kalabilen bir imkândır. Anahtarlar ve değerler karakter dizisidir; nesneyi doğrudan koymak yerine 25.3'teki JSON dönüşümünü kullanabiliriz.1213
function puaniSakla(puan) {
try {
localStorage.setItem("hukuk-deneme:puan", JSON.stringify({ puan: puan }));
return true;
} catch (hata) {
return false;
}
}
function puaniOku() {
try {
const metin = localStorage.getItem("hukuk-deneme:puan");
if (metin === null) return 0;
const kayit = JSON.parse(metin);
if (kayit === null || typeof kayit !== "object") return 0;
if (!Number.isInteger(kayit.puan) || kayit.puan < 0) return 0;
return kayit.puan;
} catch (hata) {
return 0;
}
}
Bu, ana örneğe otomatik bağlanmayan ayrı bir saklama deneyidir. İlk fonksiyon JSON kaydı yazar; engellenme veya alan sınırı hatasında false döndürür. İkincisi aynı anahtarı okur: kayıt yoksa sıfır; varsa ayrıştırma, nesne ve negatif olmayan tamsayı denetimleri yapılır. Geçerli puan döner, hata yakalanırsa sıfır seçilir. Bu kurtarma politikası her üründe sessiz veri kaybını önermez.121310
Konsolda puaniSakla(10) ve puaniOku() çağır; yenileyip tekrar oku. localStorage.removeItem("hukuk-deneme:puan") yalnız bu anahtarı siler. Tam oturum yüklemek ayrı iştir: soru indeksi, cevaplandı bayrağı ve soru sürümü de uyuşmalıdır. Örneğimiz bunu çözmüş gibi davranmıyor.
Saklama alanı köken (origin) ile ilişkilidir: şema, alan adı, port. HTTP ve HTTPS aynı alan değildir. Veri silinebilir; özel gezinme/politikalar kalıcılığı sınırlayabilir. file:// davranışını garanti sayma; deneyi aynı yerel HTTP adresinde yap. Geliştirme sunucusu Bölüm 29’da.1213
Çerez aynı kutunun başka adı değil
Çerez (cookie), tarayıcıda tutulabilen ve kapsam/kurallar elverdiğinde ilgili HTTP istekleriyle gönderilen küçük veridir. localStorage içindeki puan ise her HTTP isteğine kendiliğinden eklenmez. Bu fark, oturum yönetiminde önemlidir: sunucu bir oturum kimliğini çerez üzerinden ilişkilendirebilir. Burada parola veya gerçek oturum belirteci saklayan örnek yazmıyoruz; bu, Bölüm 41'in güvenlik konusudur.14
HttpOnly JavaScript’in çereze erişimini sınırlayabilir; Secure ve SameSite gönderim/güvenlik kuralları taşır. Bütün çerezler JavaScript’ten okunabilir değildir. Kullanıcı yerel kaydını değiştirebildiğinden tip denetimi puanın dürüst kazanıldığını kanıtlamaz.14
26.5 fetch ile sunucuya istek: HTTP ve JSON'a köprü
Artık aynı tarayıcının içindeki iki ilişkiyi ayırabiliyoruz: durum nesnesi ile DOM; durumun geçici hali ile saklanmış metni. Üçüncü sınır ağdır. Fetch API (Fetch API), HTTP isteği yapıp yanıtı işlemek için kullanılır. fetch çağrısı bir Promise döndürür; sonuçlandığında elimizde doğrudan soru nesnesi değil, önce bir Response nesnesi vardır. Yanıtın gövdesini ayrıca okuruz.15
async function siralamayiOku() {
const yanit = await fetch("/api/leaderboard");
if (!yanit.ok) throw new Error(`HTTP hatası: ${yanit.status}`);
const veri = await yanit.json();
if (!Array.isArray(veri)) throw new Error("Dizi biçiminde yanıt bekleniyordu.");
return veri;
}
Bu varsayımsal uç nokta projede çalışan servis veya gerçek sunucu çıktısı iddiası değildir. İlk satır fonksiyonu kurar; ikincisi kökteki yola GET başlatıp yanıtı bekler. Üçüncü satır HTTP durumunu denetler: 404/500, tek başına Promise’i reddettirmez. Dördüncü satır JSON gövdesini bekler; o da hata verebilir. Beşinci satır yalnız üst düzey diziyi denetler; satır alanlarını değil. Son satır veriyi döndürür.1510
async function siralamaYukle() {
sonuc.textContent = "Sıralama yükleniyor…";
try {
const satirlar = await siralamayiOku();
sonuc.textContent = `${satirlar.length} kayıt alındı.`;
} catch (hata) {
sonuc.textContent = "Sıralama alınamadı; daha sonra tekrar dene.";
}
}
Önce bekleme mesajı yazılır, try içinde okuma beklenir, başarıda dizi uzunluğu; catch içinde hata mesajı gösterilir. Bu fonksiyonu ana karta bağlamıyoruz: aynı sonuc alanını sıralama ve cevap için paylaşmak mesajları ezebilir; üründe ayrı çıktı alanı gerekir. Gösterilen, bekleme–başarı–hata örüntüsüdür.1516
Ağ hatası, HTTP hata yanıtı, geçersiz JSON ve yanlış biçim ayrı sınırlardır. Başka kökene istek CORS kurallarına tabidir; no-cors bu politikayı aşıp JSON’u okunabilir yapmaz. Yöntemler, çerez gönderimi ve CORS Bölüm 35’te açılacak.15
Üründe istemci “şu puanı kazandım, inan” demek yerine cevabı iletir; güvenilir kararı arka uç verir. Örneğin doğru indeksi JS dizisinde tutması yerel öğretim içindir, ortak sıralamanın güvenlik tasarımı değil. Bölüm 34 bu sınırı büyütecek.
Bölüm 5 durumu, Bölüm 14 bekleyiş/çalışma ayrımını kurmuştu. 23 belgeyi, 24 sunumu, 25 dili verdi. Şimdi eylem dili çalıştırıyor, durum değişiyor, DOM güncelleniyor. Bölüm 27 büyüyen betiği sorumluluklara ayıracak.
Bu bölümde neler kuruldu
DOM API ile öğeyi bulur, oluşturur ve metnini değiştiririz. Olay dinleyicileri dili kullanıcı eylemlerine bağlar. Durumu ayrı veride tutup ekrana yansıtmak, aynı soruyu iki kez değerlendirme gibi hataları görünür kılar. localStorage bir metin deposudur, ortak puan otoritesi değildir; çerezlerin HTTP ilişkisi farklıdır. fetch önce yanıt nesnesi, sonra okunacak gövde verir; ağ, HTTP, JSON ve biçim hatalarını ayırırız.
Terimler sözlükte, Bölüm 26 başlığı altında. İkinci anlatım için CS50’nin yazılı Hafta 8 notlarındaki ilgili HTML/CSS/JavaScript bölümleri de bu iş bölümünü örnekler.17
MDN · DOM scripting: Doing some basic DOM manipulation ve Creating and placing new nodes. Derinleşme: MDN · Introduction to events — Using addEventListener() ve Preventing default behavior; MDN · Using the Fetch API — Making a request ve Handling the response.
Takıldığın yeri yapay zekâ öğretmenine sor. Öğretmeninden iki kartlık örnekte ikinci gönderme, sıfır can, eksik seçim ve bozuk yerel kayıt senaryolarını sana sordurmasını iste. Her biri için değişmesi gereken durumu ve değişmemesi gereken puanı önce sen söyle.
Bölüm sonu soruları
Önce kitaba bakmadan cevapla; sonra gerekçeyi ve ilgili alt bölümü oku.
Örnek cevabı göster
submit olayı gelir; varsayılan gönderim iptal edilir; cevaplandı bayrağı zaten true ise erken dönülür. İlk geçerli cevap durumu ve puanı değiştirir; ekran yenilenir, alanlar ve kontrol düğmesi kapatılır. Kullanıcı kendi tarayıcısını değiştirebileceğinden ortak puan için sunucuda doğrulama ve tekrar işleme denetimi yine gerekir. Bkz. 26.3.
Örnek cevabı göster
JSON'un sözdiziminin geçerli olması, alanların doğru tipte ve birbiriyle tutarlı olduğunu ya da dürüst kazanıldığını kanıtlamaz. İndeks, soru sürümü ve cevap bayrağı ayrıca doğrulanmalıdır. fetch tarafında ağ hatası, HTTP hata durumu, geçersiz JSON ve yanlış veri biçimi ayrı denetlenir. Bkz. 26.5.
Kaynaklar
- MDN · DOM scripting.
- MDN · Document.querySelector().
- MDN · Node.textContent.
- MDN · Element.classList.
- MDN · Introduction to events.
- MDN · input type="radio".
- MDN · Element: input event.
- MDN · HTMLFormElement: submit event.
- MDN · Event bubbling.
- Dil ve veri işlemleri için yazılı başvuru: JavaScript data structures; Grammar and types; Working with JSON; Number.isInteger(); Array.isArray().
- MDN · ARIA: status role.
- MDN · Using the Web Storage API.
- MDN · Window.localStorage.
- MDN · Using HTTP cookies.
- MDN · Using the Fetch API.
- MDN · How to use promises.
- CS50 · Lecture 8 notes, JavaScript başlığı.