Než se dostaneme ke klávesnici, všimněte si prosím, že na moderních zařízeních existují jiné způsoby, jak „něco zadat“. Lidé například používají rozpoznávání řeči (zejména na mobilních zařízeních) nebo kopírování/vkládání pomocí myši.
Pokud tedy chceme sledovat jakýkoli vstup do <input>
pole, pak události klávesnice nestačí. Je tu další událost s názvem input
sledovat změny <input>
pole, jakýmkoli způsobem. A pro takový úkol to může být lepší volba. Probereme to později v kapitole Události:změna, zadání, vyjmutí, kopírování, vložení.
Události klávesnice by se měly používat, když chceme ovládat akce klávesnice (počítá se i virtuální klávesnice). Chcete-li například reagovat na klávesy se šipkami Nahoru a Dolů nebo klávesové zkratky (včetně kombinací kláves).
Testovací stojan
Chcete-li lépe porozumět událostem klávesnice, můžete použít níže uvedený teststand.
Vyzkoušejte různé kombinace kláves v textovém poli.
Resultscript.jsstyle.cssindex.htmlkinput.onkeydown = kinput.onkeyup = kinput.onkeypress = handle;
let lastTime = Date.now();
function handle(e) {
if (form.elements[e.type + 'Ignore'].checked) return;
area.scrollTop = 1e6;
let text = e.type +
' key=' + e.key +
' code=' + e.code +
(e.shiftKey ? ' shiftKey' : '') +
(e.ctrlKey ? ' ctrlKey' : '') +
(e.altKey ? ' altKey' : '') +
(e.metaKey ? ' metaKey' : '') +
(e.repeat ? ' (repeat)' : '') +
"\n";
if (area.value && Date.now() - lastTime > 250) {
area.value += new Array(81).join('-') + '\n';
}
lastTime = Date.now();
area.value += text;
if (form.elements[e.type + 'Stop'].checked) {
e.preventDefault();
}
}
#kinput {
font-size: 150%;
box-sizing: border-box;
width: 95%;
}
#area {
width: 95%;
box-sizing: border-box;
height: 250px;
border: 1px solid black;
display: block;
}
form label {
display: inline;
white-space: nowrap;
}
<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="style.css">
</head>
<body>
<form id="form" onsubmit="return false">
Prevent default for:
<label>
<input type="checkbox" name="keydownStop" value="1"> keydown</label>
<label>
<input type="checkbox" name="keyupStop" value="1"> keyup</label>
<p>
Ignore:
<label>
<input type="checkbox" name="keydownIgnore" value="1"> keydown</label>
<label>
<input type="checkbox" name="keyupIgnore" value="1"> keyup</label>
</p>
<p>Focus on the input field and press a key.</p>
<input type="text" placeholder="Press keys here" id="kinput">
<textarea id="area" readonly></textarea>
<input type="button" value="Clear" onclick="area.value = ''" />
</form>
<script src="script.js"></script>
</body>
</html>
Stisknutí klávesy a klávesa
keydown
události nastanou, když je stisknuta klávesa a poté keyup
– až bude vydán.
event.code a event.key
key
vlastnost objektu události umožňuje získat znak, zatímco code
vlastnost objektu události umožňuje získat „kód fyzického klíče“.
Například stejný klíč Z lze stisknout s nebo bez Shift . To nám dává dva různé znaky:malá písmena z
a velká písmena Z
.
event.key
je přesně ta postava a bude jiná. Ale event.code
je stejný:
Klíč | event.key | event.code |
---|---|---|
Z | z (malá písmena) | KeyZ |
Shift+Z | Z (velká písmena) | KeyZ |
Pokud uživatel pracuje s různými jazyky, přepnutím do jiného jazyka by vznikl zcela jiný znak namísto "Z"
. To se stane hodnotou event.key
, zatímco event.code
je vždy stejný:"KeyZ"
.
Každá klávesa má kód, který závisí na jejím umístění na klávesnici. Klíčové kódy popsané ve specifikaci kódu událostí uživatelského rozhraní.
Například:
- Klávesy s písmeny mají kódy
"Key<letter>"
:"KeyA"
,"KeyB"
atd. - Číselné klíče mají kódy:
"Digit<number>"
:"Digit0"
,"Digit1"
atd. - Speciální klíče jsou kódovány svými názvy:
"Enter"
,"Backspace"
,"Tab"
atd.
Existuje několik rozšířených rozložení klávesnice a specifikace poskytuje kódy kláves pro každé z nich.
Další kódy najdete v alfanumerické části specifikace nebo stačí stisknout klávesu na výše uvedeném testovacím stojanu.
Na případu záleží:"KeyZ"
, nikoli "keyZ"
Zdá se to zřejmé, ale lidé stále dělají chyby.
Vyvarujte se prosím překlepů:je to KeyZ
, nikoli keyZ
. Kontrola jako event.code=="keyZ"
nebude fungovat:první písmeno "Key"
musí být velká písmena.
Co když klíč nedává žádný znak? Například Shift nebo F1 nebo jiné. Pro tyto klíče event.key
je přibližně stejný jako event.code
:
Klíč | event.key | event.code |
---|---|---|
F1 | F1 | F1 |
Backspace | Backspace | Backspace |
Shift | Shift | ShiftRight nebo ShiftLeft |
Upozorňujeme, že event.code
přesně určuje, která klávesa je stisknuta. Například většina klávesnic má dva Shift klávesy:na levé a pravé straně. event.code
nám přesně říká, která z nich byla stisknuta, a event.key
je zodpovědný za „význam“ klávesy:co to je („Shift“).
Řekněme, že chceme zpracovat klávesovou zkratku:Ctrl+Z (nebo Cmd+Z pro Mac). Většina textových editorů na něj zachytí akci „Zpět“. Můžeme nastavit posluchače na keydown
a zkontrolujte, která klávesa je stisknuta.
Je zde dilema:v takovém posluchači bychom měli zkontrolovat hodnotu event.key
nebo event.code
?
Na jedné straně hodnota event.key
je znak, mění se v závislosti na jazyku. Pokud má návštěvník v OS několik jazyků a přepíná mezi nimi, stejná klávesa dává různé znaky. Proto má smysl zkontrolovat event.code
, je to vždy stejné.
Takhle:
document.addEventListener('keydown', function(event) {
if (event.code == 'KeyZ' && (event.ctrlKey || event.metaKey)) {
alert('Undo!')
}
});
Na druhou stranu je problém s event.code
. Pro různá rozložení klávesnice může mít stejná klávesa různé znaky.
Zde je například rozložení pro USA („QWERTY“) a německé rozložení („QWERTZ“) pod ním (z Wikipedie):
Pro stejný klíč má americké rozložení „Z“, zatímco německé rozložení má „Y“ (písmena jsou prohozena).
Doslova event.code
se bude rovnat KeyZ
pro lidi s německým rozložením, když stisknou Y .
Pokud zaškrtneme event.code == 'KeyZ'
v našem kódu pak pro lidi s německým rozložením takový test projde, když stisknou Y .
Zní to opravdu divně, ale je to tak. Specifikace takové chování výslovně zmiňuje.
Takže event.code
může odpovídat nesprávnému znaku pro neočekávané rozvržení. Stejná písmena v různých rozvrženích se mohou mapovat na různé fyzické klíče, což vede k různým kódům. Naštěstí se to děje pouze u několika kódů, např. keyA
, keyQ
, keyZ
(jak jsme viděli) a nestává se to u speciálních klíčů, jako je Shift
. Seznam najdete ve specifikaci.
Chcete-li spolehlivě sledovat znaky závislé na rozvržení, event.key
může být lepší způsob.
Na druhé straně event.code
má tu výhodu, že zůstává vždy stejný, vázaný na umístění fyzického klíče. Takže klávesové zkratky, které na to spoléhají, fungují dobře i v případě změny jazyka.
Chceme pracovat s klávesami závislými na rozvržení? Potom event.key
je správná cesta.
Nebo chceme, aby klávesová zkratka fungovala i po změně jazyka? Potom event.code
může být lepší.
Automatické opakování
Pokud je klávesa stisknuta dostatečně dlouho, začne se „automaticky opakovat“:keydown
spouští znovu a znovu, a když je uvolněn, konečně dostaneme keyup
. Je tedy normální mít mnoho keydown
a jeden keyup
.
U událostí spouštěných automatickým opakováním má objekt události event.repeat
vlastnost nastavena na true
.
Výchozí akce
Výchozí akce se liší, protože existuje mnoho možných věcí, které mohou být iniciovány klávesnicí.
Například:
- Na obrazovce se objeví postava (nejviditelnější výsledek).
- Znak je smazán (Smazat klíč).
- Stránka se posune (PageDown klíč).
- Prohlížeč otevře dialogové okno „Uložit stránku“ (Ctrl+S )
- …a tak dále.
Zabránění výchozí akci na keydown
může většinu z nich zrušit, s výjimkou speciálních klíčů založených na operačním systému. Například ve Windows Alt+F4 zavře aktuální okno prohlížeče. A neexistuje způsob, jak to zastavit tím, že zabráníte výchozí akci v JavaScriptu.
Například <input>
níže očekává telefonní číslo, takže nepřijímá klíče kromě číslic, +
, ()
nebo -
:
<script>
function checkPhoneKey(key) {
return (key >= '0' && key <= '9') || ['+','(',')','-'].includes(key);
}
</script>
<input onkeydown="return checkPhoneKey(event.key)" placeholder="Phone, please" type="tel">
onkeydown
handler zde používá checkPhoneKey
pro kontrolu stisknutého tlačítka. Pokud je platný (od 0..9
nebo jeden z +-()
), pak vrátí true
, jinak false
.
Jak víme, false
hodnota vrácená obslužnou rutinou události, přiřazená pomocí vlastnosti DOM nebo atributu, jako je výše, brání výchozí akci, takže v <input>
se nic neobjeví pro klíče, které neprojdou testem. (true
vrácená hodnota nemá na nic vliv, pouze vrací false
záleží)
Upozorňujeme, že speciální klávesy, jako je Backspace , Vlevo , Vpravo , nefungují ve vstupu. To je vedlejší efekt přísného filtru checkPhoneKey
. Tyto klíče způsobí, že vrátí false
.
Uvolněme filtr trochu tím, že povolíme klávesy se šipkami Vlevo , Vpravo a Smazat , Backspace :
<script>
function checkPhoneKey(key) {
return (key >= '0' && key <= '9') ||
['+','(',')','-','ArrowLeft','ArrowRight','Delete','Backspace'].includes(key);
}
</script>
<input onkeydown="return checkPhoneKey(event.key)" placeholder="Phone, please" type="tel">
Nyní šipky a mazání fungují dobře.
I když máme klíčový filtr, stále lze zadat cokoli pomocí myši a kliknout pravým tlačítkem + Vložit. Mobilní zařízení poskytují další prostředky pro zadávání hodnot. Filtr tedy není 100% spolehlivý.
Alternativním přístupem by bylo sledování oninput
událost – spustí se po jakákoliv úprava. Zde můžeme zkontrolovat nový input.value
a upravte jej/zvýrazněte <input>
když je neplatný. Nebo můžeme použít oba obslužné rutiny událostí společně.
Starší
V minulosti existoval keypress
událost a také keyCode
, charCode
, which
vlastnosti objektu události.
Při práci s nimi bylo tolik nekompatibilit prohlížečů, že vývojáři specifikace neměli jinou možnost, než je všechny zavrhnout a vytvořit nové, moderní události (popsané výše v této kapitole). Starý kód stále funguje, protože je prohlížeče stále podporují, ale už je není potřeba používat.
Mobilní klávesnice
Při použití virtuálních/mobilních klávesnic, formálně známých jako IME (Input-Method Editor), standard W3C uvádí, že e.keyCode
události KeyboardEvent by mělo být 229
a e.key
by mělo být "Unidentified"
.
I když některé z těchto klávesnic mohou stále používat správné hodnoty pro e.key
, e.code
, e.keyCode
… při stisknutí určitých kláves, jako jsou šipky nebo backspace, neexistuje žádná záruka, takže logika vaší klávesnice nemusí na mobilních zařízeních vždy fungovat.
Shrnutí
Stisknutí klávesy vždy vygeneruje událost klávesnice, ať už jde o klávesy se symboly nebo speciální klávesy jako Shift nebo Ctrl a tak dále. Jedinou výjimkou je Fn klíč, který se někdy vyskytuje na klávesnici notebooku. Neexistuje pro to žádná událost klávesnice, protože je často implementována na nižší úrovni než OS.
Události klávesnice:
keydown
– při stisknutí klávesy (automaticky se opakuje, pokud je klávesa stisknuta dlouho),keyup
– při uvolnění klíče.
Vlastnosti události hlavní klávesnice:
code
– „kód klíče“ ("KeyA"
,"ArrowLeft"
a tak dále), specifické pro fyzické umístění klávesy na klávesnici.key
– znak ("A"
,"a"
a tak dále), pro klávesy bez znaků, jako je Esc , má obvykle stejnou hodnotu jakocode
.
V minulosti byly události klávesnice někdy používány ke sledování uživatelského vstupu do polí formuláře. To není spolehlivé, protože vstup může pocházet z různých zdrojů. Máme input
a change
události pro zpracování jakéhokoli vstupu (popsané dále v kapitole Události:změna, zadání, vyjmutí, kopírování, vložení). Spouštějí se po jakémkoliv vstupu, včetně kopírování-vkládání nebo rozpoznávání řeči.
Události klávesnice bychom měli používat, když opravdu chceme klávesnici. Například pro reakci na klávesové zkratky nebo speciální klávesy.