Kısa cevap: Klavyeyi dinlemek için keydown ve keyup olaylarını kullanırsınız; eski keypress olayı MDN'de kullanımdan kalkmış olarak geçer. Olay nesnesindeki event.key kullanıcının klavye düzenine ve Shift gibi değiştirici tuşlara göre üretilen değeri verir (örneğin "a", "A", "Enter"), event.code ise düzenden bağımsız olarak basılan fiziksel tuşun adını verir (örneğin "KeyA"). Kısayollar ve metinle ilgili işler için key, oyunlardaki WASD gibi konuma bağlı kontroller için code seçilir. Kullanımdan kaldırılmış keyCode yerine bu iki özelliği kullanmanız önerilir.
Bu yazıda bir tuşa basıldığında hangi olayların hangi sırayla geldiğini, repeat ile basılı tutmayı, IME ile metin oluştururken isComposing kontrolünü, değiştirici tuş özelliklerini ve metin girişi için neden klavye olayları yerine beforeinput ve input olaylarının daha uygun olduğunu MDN belgelerine göre anlatıyoruz. Örnekler tarayıcıya özgüdür, çalıştırılmadı; API adları ve değerler MDN sayfalarından alındı. Dinleyici ekleme ayrıntıları için addEventListener yazısına, tüm seri için Web API öğrenme rehberi sayfasına bakın.
keydown, keyup ve keypress
KeyboardEvent arayüzü kullanıcıyla bir tuş arasındaki tek bir etkileşimi düşük düzeyde tanımlar ve MDN bu olayların etkileşime bağlamsal bir anlam yüklemediğini vurgular. Üç olay türü vardır: keydown tuşa basıldığında, keyup tuş bırakıldığında tetiklenir. keypress ise karakter üreten bir tuşa basıldığında gelen eski bir olaydır; MDN onu cihaza çok bağımlı ve kullanımdan kalkmış olarak tanımlar ve kullanmamanızı söyler. keydown karakter üretip üretmediğine bakmadan bütün tuşlar için gelir; Shift, Control veya ok tuşlarını da yakalar.
Klavye olayının hedefi, klavye etkinliğini işleyen ve o anda odakta olan öğedir: input, textarea, contenteditable içerik ya da a, button, summary gibi klavyeyle etkileşen öğeler. Uygun bir öğe odakta değilse hedef body ya da kök olur. Olay kabarcıklanır ve Document ile Window düzeyine ulaşabilir; bu yüzden sayfa genelindeki kısayolları document ya da window üzerinde dinlemek yaygın bir yöntemdir. MDN, hedefin olaydan olaya değişebileceğini de not eder: Tab tuşuna basıldığında odak değiştiği için keydown ile keyup farklı öğelerde gelir.
Bir tuş vuruşunda olay sırası
MDN KeyboardEvent.key sayfasında, preventDefault() çağrılmadığı varsayımıyla şu sırayı verir: Önce keydown gelir. Tuş karakter üretiyor ve odaktaki öğe bir input, textarea ya da düzenlenebilir içerikse ardından beforeinput ve input olayları bu sırayla gelir. Tuş bırakıldığında keyup tetiklenir. Karakter üreten bir tuş basılı tutulursa keydown platforma bağlı aralıklarla tekrar gelir ve bu tekrarlarda event.repeat değeri true olur; beforeinput ve input da tekrar eder.
MDN'nin örnek senaryosu bu sırayı somutlaştırır. ABD klavye düzeninde Shift basılıyken 2 tuşuna basıldığında önce key değeri "Shift" olan bir keydown, ardından key değeri "@" olan ikinci bir keydown gelir; İngiltere düzeninde bu değer " karakteridir. Shift tek başına basılı tutulduğunda karakter üretmediği için keydown tekrar etmez. Shift bırakılıp 2 tuşu basılı kalırsa tekrar eden keydown olaylarının key değeri artık "2" olur, çünkü değiştirici etkin değildir.
<textarea id="hedef" rows="4"></textarea>
<pre id="gunluk"></pre>const alan = document.getElementById("hedef");
const gunluk = document.getElementById("gunluk");
function yaz(mesaj) {
gunluk.textContent += `${mesaj}\n`;
}
alan.addEventListener("keydown", (e) => {
yaz(e.repeat ? `keydown (tekrar): ${e.key}` : `keydown: ${e.key}`);
});
alan.addEventListener("beforeinput", (e) => {
yaz(`beforeinput: ${e.data}`);
});
alan.addEventListener("input", (e) => {
yaz(`input: ${e.data}`);
});
alan.addEventListener("keyup", (e) => {
yaz(`keyup: ${e.key}`);
});Bu kod MDN örneğinin sadeleştirilmiş hâlidir; beforeinput ve input olaylarında karakter key özelliğinden değil InputEvent.data özelliğinden okunur. MDN, InputEvent arayüzünü tam uygulamayan tarayıcılarda bu iki satırın beklenenden farklı çıktı verebileceğini not eder.
key ile code arasındaki fark

event.key değeri değiştirici tuşların durumunu, klavyenin yerel ayarını ve düzenini hesaba katar. Basılan tuşun yazdırılabilir bir karşılığı varsa sonuç o karakterdir: B tuşu için "b", Shift ile birlikte "B", boşluk çubuğu için tek bir boşluk karakteri. Kontrol ya da özel tuşlarda MDN'nin önceden tanımlı tuş değerleri listesinden biri gelir; "Enter", "Escape", "ArrowUp", "Shift" bunlara örnektir. Ölü tuşlarda değer "Dead", tanımlanamayan tuşlarda "Unidentified" olur.
event.code ise fiziksel tuşu temsil eder ve düzenden ya da değiştiricilerden etkilenmez. MDN'nin örneğine göre QWERTY düzeninde Q tuşu için code değeri "KeyQ" olur; aynı değer Dvorak düzeninde tek tırnak tuşunu, AZERTY düzeninde A tuşunu da temsil eder. Bu nedenle code değerini kullanıcıya hangi tuşa bastığını göstermek için kullanamazsınız. Türkçe Q ya da F klavyede de mantık aynıdır: code tuşun konumunu, key o konumdan seçili düzene göre çıkan karakteri anlatır. Sanal klavyelerde ve erişilebilirlik cihazlarında tarayıcı code değerini fiziksel klavyeye olabildiğince yakın ayarlar.
| Durum | event.key | event.code |
|---|---|---|
| B tuşu, Shift yok | b | KeyB |
| B tuşu, Shift basılı | B | KeyB |
| Boşluk çubuğu | tek boşluk karakteri | Space |
| Sol ok | ArrowLeft | ArrowLeft |
| ABD düzeni, Shift ile 2 | @ | Digit2 |
| QWERTY düzeninde Q konumu, AZERTY klavye | a | KeyQ |
Tablodaki Space ve Digit2 adları MDN'nin code değerleri listesindeki adlandırma kuralını izler. Uygulamanızın bir tuşa hangi adla tepki vereceğini seçerken şu soruyu sorun: Kullanıcı bu tuşu üzerindeki harf yüzünden mi, yoksa klavyedeki yeri yüzünden mi kullanıyor? Kaydet kısayolu için S harfi önemlidir, bu yüzden key; bir oyunda ileri gitmek için kullanıcının W konumundaki tuşa basması önemlidir, bu yüzden code.
Kısayol yakalama örneği

MDN'nin key sayfasındaki örnek, window üzerinde keydown dinler, olay daha önce işlendiyse defaultPrevented ile çıkar, ilgilendiği tuşlarda iş yapar ve sonunda olayın iki kez işlenmemesi için preventDefault() çağırır. Aşağıdaki kod aynı deseni Ctrl ya da Meta ile birlikte S tuşuna uygular.
window.addEventListener("keydown", (event) => {
if (event.defaultPrevented) {
return; // başka bir dinleyici bu olayı zaten işledi
}
const kontrol = event.ctrlKey || event.metaKey;
if (kontrol && event.key.toLowerCase() === "s") {
event.preventDefault(); // tarayıcının kendi kaydet davranışını engeller
taslakKaydet();
return;
}
switch (event.key) {
case "Escape":
paneliKapat();
break;
case "ArrowDown":
sonrakiSatir();
break;
case "ArrowUp":
oncekiSatir();
break;
default:
return; // ilgilenmediğimiz tuş, varsayılan davranışa dokunma
}
event.preventDefault();
});Shift basılıyken key büyük harf döndürdüğü için karşılaştırmadan önce toLowerCase() uygulamak, Ctrl+Shift+S gibi bir birleşimin de yakalanmasına yol açar; ikisini ayırmak istiyorsanız event.shiftKey değerine ayrıca bakın. Kısayolu yazarken kullanıcı bir metin alanına yazı yazıyorsa çakışma olup olmayacağını da düşünün; gerekirse event.target değerini kontrol edip form alanlarında kısayolu devre dışı bırakın.
Oyun kontrolü: code ile konuma göre tuşlar
MDN'nin code sayfasındaki oyun örneği, WASD tuşlarını ve ok tuşlarını event.code ile eşleştirir. Böylece AZERTY klavye kullanan biri aynı fiziksel konumdaki ZQSD tuşlarıyla oynayabilir. Örnekte Tab tuşu dışındaki tuşlarda preventDefault() çağrılır; Tab serbest bırakılır ki kullanıcı odağı oyun alanının dışına taşıyabilsin.
window.addEventListener("keydown", (event) => {
if (event.defaultPrevented) {
return;
}
switch (event.code) {
case "KeyW":
case "ArrowUp":
ileri();
break;
case "KeyS":
case "ArrowDown":
geri();
break;
case "KeyA":
case "ArrowLeft":
solaDon();
break;
case "KeyD":
case "ArrowRight":
sagaDon();
break;
}
if (event.code !== "Tab") {
event.preventDefault(); // odak taşıma dışında olayı tüket
}
});MDN bu örneğin geliştirilebileceğini de söyler: Gerçek oyunların çoğu tuş tekrarına güvenmek yerine keydown geldiğinde hareketi başlatır, ilgili keyup geldiğinde durdurur. Bu yaklaşım daha akıcı hareket sağlar ve aynı anda hem ilerleyip hem dönmeye izin verir. Hareketi her karede güncellemek için requestAnimationFrame yazısına bakabilirsiniz.
Değiştirici tuşlar ve keyup ayrıntısı
altKey, ctrlKey, metaKey ve shiftKey özellikleri olay üretildiği anda ilgili değiştiricinin etkin olup olmadığını boolean olarak verir. MDN, Meta tuşunun Mac klavyelerinde Command, Windows klavyelerinde Windows tuşu olduğunu belirtir. keyup sayfasındaki ayrıntı önemlidir: Olay tuş bırakıldıktan sonra geldiği için değiştirici özellikleri bırakma sonrasındaki durumu yansıtır. Control tuşunun kendi keyup olayında ctrlKey değeri false olur; Control basılı kalırken başka bir tuş bırakılırsa o tuşun keyup olayında ctrlKey true olur.
getModifierState(key) yöntemi belirli bir değiştiricinin basılı ya da kilitli olup olmadığını sorar. Parametre, değiştirici tuşları temsil eden key değerlerinden biri ya da "Accel" olmalıdır ve büyük küçük harfe duyarlıdır. Bu yöntemle CapsLock ya da ScrollLock gibi kilit tuşlarının durumunu da öğrenebilirsiniz. MDN, Alt, Control, Meta ve Shift için doğrudan özelliklerin daha tercih edilebilir olabileceğini not eder. location özelliği ise tuşun klavyedeki bölgesini sayı olarak verir: standart için 0, sol için 1, sağ için 2, sayısal tuş takımı için 3; böylece sol ve sağ Shift ayrılabilir.
document.addEventListener("keydown", (event) => {
if (event.getModifierState("CapsLock")) {
capsUyarisiGoster(); // şifre alanında büyük harf kilidi uyarısı
}
if (event.key === "Shift" && event.location === KeyboardEvent.DOM_KEY_LOCATION_RIGHT) {
sagShiftBasildi();
}
});IME ve isComposing kontrolü
Çince, Japonca ya da Korece gibi dillerde metin bir giriş yöntemi düzenleyicisi (IME) ile oluşturulur; kullanıcı birkaç tuşa basarak tek bir karakteri seçer. Bu süreç compositionstart ile başlar, compositionend ile biter. Aradaki klavye olaylarında event.isComposing değeri true olur. Enter tuşuyla bir mesajı göndermek gibi bir kısayolunuz varsa, kullanıcı IME penceresinde seçim yapmak için Enter'a bastığında mesajı yanlışlıkla göndermemek için bu değeri kontrol etmeniz gerekir.
mesajAlani.addEventListener("keydown", (event) => {
if (event.isComposing || event.keyCode === 229) {
return; // metin hâlâ IME ile oluşturuluyor
}
if (event.key === "Enter" && !event.shiftKey) {
event.preventDefault();
mesajiGonder();
}
});Burada keyCode kontrolünün neden bulunduğunu MDN açıklar: compositionstart, IME'yi açan ilk karakterde keydown olayından sonra, compositionend ise IME'yi kapatan son karakterde keydown olayından önce gelebilir. Bu durumlarda isComposing false olsa da keyCode değeri yine 229 olur. Bu yüzden MDN, kullanımdan kalkmış olsa da bu özel amaçla keyCode değerine de bakmayı önerir. keyup için 229 gibi özel bir değer yoktur.
Metin girişi için beforeinput ve input
MDN klavye olaylarının yalnızca tuşla yapılan düşük düzeyli etkileşimi anlattığını ve metin girişini ele almanız gerektiğinde input olayını kullanmanızı söyler. Gerekçe basittir: Kullanıcı metni el yazısı tanıma, yapıştırma, otomatik doldurma, sesli giriş ya da yazım denetimi önerisi gibi klavye dışı yollarla da girebilir ve bu durumlarda klavye olayları hiç gelmeyebilir. input olayı, değeri kullanıcı eylemiyle değişen input, select ve textarea öğelerinde ve düzenlenebilir içerikte tetiklenir. Değer betikle atandığında ya da form sıfırlandığında ise tetiklenmez.
beforeinput değer değişmeden hemen önce gelir ve tarayıcı DOM'u değiştirmeden önce davranışı değiştirmenize olanak tanır; select öğesinde tetiklenmez. MDN her kullanıcı değişikliğinin beforeinput üretmediğini ve bazen olayın iptal edilemez olarak gelebileceğini, örneğin otomatik tamamlama, şifre yöneticisi ya da IME durumlarında, açıkça uyarır. Bu yüzden düzenleme davranışını her durumda değiştirmek istiyorsanız input olayını da işleyip beforeinput tarafından yakalanmayan değişiklikleri geri almanız gerekebilir. InputEvent.inputType değişikliğin türünü insertText, deleteContentBackward, insertFromPaste gibi değerlerle anlatır.
const kod = document.querySelector("#kupon");
kod.addEventListener("beforeinput", (event) => {
// yalnızca rakam ve harf eklenmesine izin ver
if (event.inputType === "insertText" && /[^0-9a-z]/i.test(event.data ?? "")) {
event.preventDefault();
}
});
kod.addEventListener("input", () => {
kod.value = kod.value.toUpperCase(); // yapıştırma gibi yolları da kapsar
});Bu tür alanlarda tarayıcının yerleşik doğrulamasını (pattern, maxlength gibi öznitelikler) tercih etmek çoğu zaman daha az kodla daha erişilebilir sonuç verir; HTML tarafı için HTML öğrenme rehberine, formun gönderilmesi için FormData ve submit yazısına bakın.
Neden keyCode kullanılmamalı?
MDN keyCode özelliğini kullanımdan kaldırılmış olarak tanımlar ve mümkünse kaçınmanızı söyler. Değer sisteme ve uygulamaya bağlı bir sayıdır; yazdırılabilir tuşlarda tarayıcılar arasında uyumlu değildir ve Shift ya da Alt ile girilen karakterler için işe yaramaz. Sayfada verilen örneklerden birine göre Rusça düzende hem nokta hem eğik çizgi tuşu aynı 190 değerini alabilir. Bunun yerine fiziksel tuş için code, üretilen karakter için key kullanın. Aynı şekilde charCode ve keyIdentifier da MDN'de eski özellikler arasında yer alır.
Sık yapılan hatalar

- keypress kullanmak: Kullanımdan kalkmış ve cihaza bağımlıdır;
keydownya da metin içininputkullanın. - Harf kısayolunda code kullanmak: Farklı düzendeki kullanıcı başka bir harfe basmak zorunda kalır. Harf anlamı önemliyse
keykullanın. - Oyun kontrolünde key kullanmak: AZERTY ya da Dvorak kullanıcıları için tuşlar yanlış konuma düşer; konum önemliyse
codekullanın. - Tab tuşunu engellemek: Her tuşta
preventDefault()çağırmak klavye kullanıcılarının odağı taşımasını engeller. - IME durumunu yok saymak: Enter ile gönderim yapan alanlarda
isComposingkontrolü yapılmazsa yarım kalmış metin gönderilir. - Klavye olayıyla metin doğrulamak: Yapıştırma ve otomatik doldurma klavye olayı üretmeyebilir;
inputolayını kullanın. - keyup içinde ctrlKey ile Control bırakılışını aramak: Control'ün kendi
keyupolayındactrlKeyzatenfalseolur; bunun yerineevent.key === "Control"kontrol edin.
Sık Sorulan Sorular
Klavye olaylarını nerede dinlemeliyim?
Bir alana özgü davranış için o alanın kendisinde, sayfa genelindeki kısayollar için document ya da window üzerinde. Olay odaktaki öğeden başlar ve kabarcıklanarak yukarı çıkar; ayrıntı için olay yayılımı yazısına bakın.
Basılı tutulan bir tuşu nasıl anlarım?
keydown olayındaki event.repeat değeri tuş otomatik tekrar ederken true olur. MDN bazı GTK tabanlı ortamlarda otomatik tekrarın araya keyup olayları ekleyebildiğini ve bu ortamlarda tekrar ile art arda basmayı ayırmanın mümkün olmadığını da not eder.
event.key Türkçe karakterleri döndürür mü?
key değeri seçili klavye düzenine ve yerel ayara göre üretilen karakteri verdiği için düzende o karakteri üreten tuşa basıldığında karakterin kendisini döndürür. Fiziksel konum bilgisi gerekiyorsa code değerine bakın; kullanıcıya düzene göre doğru tuş adını göstermek için MDN Keyboard.getLayoutMap() yöntemini işaret eder, desteği için MDN uyumluluk tablosuna bakın.
Sentetik KeyboardEvent ile tuşa basmış gibi yapabilir miyim?
KeyboardEvent() yapıcısıyla olay oluşturup dispatchEvent() ile gönderebilirsiniz. Ancak MDN'ye göre dispatchEvent() ile gönderilen olayların isTrusted değeri false olur, yani kodunuz bu olayı gerçek kullanıcı girdisinden ayırt edebilir. Eski initKeyboardEvent() yöntemi kullanımdan kalkmıştır, yerine yapıcıyı kullanın. Kendi olaylarınızı tasarlamak için CustomEvent yazısına bakın.
Marka adları sahiplerine aittir. Bu yazı bağımsız bir teknik rehberdir; adı geçen kuruluşlarla bayilik veya ortaklık ilişkisi bulunduğu anlamına gelmez.
İlgili içerikler: Web API öğrenme rehberi · addEventListener kullanımı · Olay yayılımı ve delegasyon · Pointer events · Form gönderme ve FormData · Clipboard API