- Keyboard: keydown and keyup
- Teststand
- Keydown and keyup
- event.code and event.key
- Auto-repeat
- Default actions
- Legacy
- Mobile Keyboards
- Summary
- Tasks
- Extended hotkeys
- Comments
- JavaScript: Информация О Нажатой Клавише 👇🏽
- Выполнение кода в зависимости от нажатой клавиши
- Как отследить комбинации нажатых клавиш
- Информация о нажатой кнопке мыши JavaScript
- Статьи из данной категории:
Keyboard: keydown and keyup
Before we get to keyboard, please note that on modern devices there are other ways to “input something”. For instance, people use speech recognition (especially on mobile devices) or copy/paste with the mouse.
So if we want to track any input into an field, then keyboard events are not enough. There’s another event named input to track changes of an field, by any means. And it may be a better choice for such task. We’ll cover it later in the chapter Events: change, input, cut, copy, paste.
Keyboard events should be used when we want to handle keyboard actions (virtual keyboard also counts). For instance, to react on arrow keys Up and Down or hotkeys (including combinations of keys).
Teststand
To better understand keyboard events, you can use the teststand below.
Try different key combinations in the text field.
kinput.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(); >>
Keydown and keyup
The keydown events happens when a key is pressed down, and then keyup – when it’s released.
event.code and event.key
The key property of the event object allows to get the character, while the code property of the event object allows to get the “physical key code”.
For instance, the same key Z can be pressed with or without Shift . That gives us two different characters: lowercase z and uppercase Z .
The event.key is exactly the character, and it will be different. But event.code is the same:
Key | event.key | event.code |
---|---|---|
Z | z (lowercase) | KeyZ |
Shift + Z | Z (uppercase) | KeyZ |
If a user works with different languages, then switching to another language would make a totally different character instead of «Z» . That will become the value of event.key , while event.code is always the same: «KeyZ» .
Every key has the code that depends on its location on the keyboard. Key codes described in the UI Events code specification.
- Letter keys have codes «Key» : «KeyA» , «KeyB» etc.
- Digit keys have codes: «Digit» : «Digit0» , «Digit1» etc.
- Special keys are coded by their names: «Enter» , «Backspace» , «Tab» etc.
There are several widespread keyboard layouts, and the specification gives key codes for each of them.
Read the alphanumeric section of the spec for more codes, or just press a key in the teststand above.
Seems obvious, but people still make mistakes.
Please evade mistypes: it’s KeyZ , not keyZ . The check like event.code==»keyZ» won’t work: the first letter of «Key» must be uppercase.
What if a key does not give any character? For instance, Shift or F1 or others. For those keys, event.key is approximately the same as event.code :
Key | event.key | event.code |
---|---|---|
F1 | F1 | F1 |
Backspace | Backspace | Backspace |
Shift | Shift | ShiftRight or ShiftLeft |
Please note that event.code specifies exactly which key is pressed. For instance, most keyboards have two Shift keys: on the left and on the right side. The event.code tells us exactly which one was pressed, and event.key is responsible for the “meaning” of the key: what it is (a “Shift”).
Let’s say, we want to handle a hotkey: Ctrl + Z (or Cmd + Z for Mac). Most text editors hook the “Undo” action on it. We can set a listener on keydown and check which key is pressed.
There’s a dilemma here: in such a listener, should we check the value of event.key or event.code ?
On one hand, the value of event.key is a character, it changes depending on the language. If the visitor has several languages in OS and switches between them, the same key gives different characters. So it makes sense to check event.code , it’s always the same.
document.addEventListener('keydown', function(event) < if (event.code == 'KeyZ' && (event.ctrlKey || event.metaKey)) < alert('Undo!') >>);
On the other hand, there’s a problem with event.code . For different keyboard layouts, the same key may have different characters.
For example, here are US layout (“QWERTY”) and German layout (“QWERTZ”) under it (from Wikipedia):
For the same key, US layout has “Z”, while German layout has “Y” (letters are swapped).
Literally, event.code will equal KeyZ for people with German layout when they press Y .
If we check event.code == ‘KeyZ’ in our code, then for people with German layout such test will pass when they press Y .
That sounds really odd, but so it is. The specification explicitly mentions such behavior.
So, event.code may match a wrong character for unexpected layout. Same letters in different layouts may map to different physical keys, leading to different codes. Luckily, that happens only with several codes, e.g. keyA , keyQ , keyZ (as we’ve seen), and doesn’t happen with special keys such as Shift . You can find the list in the specification.
To reliably track layout-dependent characters, event.key may be a better way.
On the other hand, event.code has the benefit of staying always the same, bound to the physical key location. So hotkeys that rely on it work well even in case of a language switch.
Do we want to handle layout-dependant keys? Then event.key is the way to go.
Or we want a hotkey to work even after a language switch? Then event.code may be better.
Auto-repeat
If a key is being pressed for a long enough time, it starts to “auto-repeat”: the keydown triggers again and again, and then when it’s released we finally get keyup . So it’s kind of normal to have many keydown and a single keyup .
For events triggered by auto-repeat, the event object has event.repeat property set to true .
Default actions
Default actions vary, as there are many possible things that may be initiated by the keyboard.
- A character appears on the screen (the most obvious outcome).
- A character is deleted ( Delete key).
- The page is scrolled ( PageDown key).
- The browser opens the “Save Page” dialog ( Ctrl + S )
- …and so on.
Preventing the default action on keydown can cancel most of them, with the exception of OS-based special keys. For instance, on Windows Alt + F4 closes the current browser window. And there’s no way to stop it by preventing the default action in JavaScript.
For instance, the below expects a phone number, so it does not accept keys except digits, + , () or — :
function checkPhoneKey(key) < return (key >= '0' && key
The onkeydown handler here uses checkPhoneKey to check for the key pressed. If it’s valid (from 0..9 or one of +-() ), then it returns true , otherwise false .
As we know, the false value returned from the event handler, assigned using a DOM property or an attribute, such as above, prevents the default action, so nothing appears in the for keys that don’t pass the test. (The true value returned doesn’t affect anything, only returning false matters)
Please note that special keys, such as Backspace , Left , Right , do not work in the input. That’s a side effect of the strict filter checkPhoneKey . These keys make it return false .
Let’s relax the filter a little bit by allowing arrow keys Left , Right and Delete , Backspace :
function checkPhoneKey(key) < return (key >= '0' && key
Now arrows and deletion works well.
Even though we have the key filter, one still can enter anything using a mouse and right-click + Paste. Mobile devices provide other means to enter values. So the filter is not 100% reliable.
The alternative approach would be to track the oninput event – it triggers after any modification. There we can check the new input.value and modify it/highlight the when it’s invalid. Or we can use both event handlers together.
Legacy
In the past, there was a keypress event, and also keyCode , charCode , which properties of the event object.
There were so many browser incompatibilities while working with them, that developers of the specification had no way, other than deprecating all of them and creating new, modern events (described above in this chapter). The old code still works, as browsers keep supporting them, but there’s totally no need to use those any more.
Mobile Keyboards
When using virtual/mobile keyboards, formally known as IME (Input-Method Editor), the W3C standard states that a KeyboardEvent’s e.keyCode should be 229 and e.key should be «Unidentified» .
While some of these keyboards might still use the right values for e.key , e.code , e.keyCode … when pressing certain keys such as arrows or backspace, there’s no guarantee, so your keyboard logic might not always work on mobile devices.
Summary
Pressing a key always generates a keyboard event, be it symbol keys or special keys like Shift or Ctrl and so on. The only exception is Fn key that sometimes presents on a laptop keyboard. There’s no keyboard event for it, because it’s often implemented on lower level than OS.
- keydown – on pressing the key (auto-repeats if the key is pressed for long),
- keyup – on releasing the key.
Main keyboard event properties:
- code – the “key code” ( «KeyA» , «ArrowLeft» and so on), specific to the physical location of the key on keyboard.
- key – the character ( «A» , «a» and so on), for non-character keys, such as Esc , usually has the same value as code .
In the past, keyboard events were sometimes used to track user input in form fields. That’s not reliable, because the input can come from various sources. We have input and change events to handle any input (covered later in the chapter Events: change, input, cut, copy, paste). They trigger after any kind of input, including copy-pasting or speech recognition.
We should use keyboard events when we really want keyboard. For example, to react on hotkeys or special keys.
Tasks
Extended hotkeys
Create a function runOnKeys(func, code1, code2, . code_n) that runs func on simultaneous pressing of keys with codes code1 , code2 , …, code_n .
For instance, the code below shows alert when «Q» and «W» are pressed together (in any language, with or without CapsLock)
runOnKeys( () => alert("Hello!"), "KeyQ", "KeyW" );
We should use two handlers: document.onkeydown and document.onkeyup .
Let’s create a set pressed = new Set() to keep currently pressed keys.
The first handler adds to it, while the second one removes from it. Every time on keydown we check if we have enough keys pressed, and run the function if it is so.
Comments
- If you have suggestions what to improve — please submit a GitHub issue or a pull request instead of commenting.
- If you can’t understand something in the article – please elaborate.
- To insert few words of code, use the tag, for several lines – wrap them in tag, for more than 10 lines – use a sandbox (plnkr, jsbin, codepen…)
JavaScript: Информация О Нажатой Клавише 👇🏽
В данной статье рассмотрим, как получить информацию о нажатой клавише клавиатуры или кнопки мыши, а также как выполнять необходимые действия (нужный код) при нажатии определенных сочетаний клавиш или кнопок (правый/левый клик мыши).
Чтобы получить информацию, о том какая кнопка клавиатуры нажимается в данный момент, воспользуемся следующим кодом:
function keyPress(e) < let keyNum; if (window.event) < keyNum = window.event.keyCode; >else if (e) < keyNum = e.which; >console.log(keyNum); > document.onkeydown = keyPress;
Номер кнопки находится в переменной keyNum
Узнать keyCode кнопки можете здесь:
Выполнение кода в зависимости от нажатой клавиши
Давайте теперь будем выполнять необходимые действия в зависимости от нажатой клавиши
Для этой задачи воспользуемся оператором switch .
В конструкции case укажите номер кнопки, для которой будет выполнен необходимый код.
document.onkeydown = function (e) < switch (e.keyCode) < case 49: console.log("Нажата единица"); break; case 50: console.log("Нажата двойка"); break; case 32: console.log("Нажат пробел"); break; case 9: console.log("Нажат tab"); break; case 16: console.log("Нажат shift"); break; default: console.log(e.keyCode); >>;
Вместо console.log выполняйте необходимые действия.
Если была нажата клавиша, которой нет в списке, то для неё можете выполнить другой код. Писать в default.
Как отследить комбинации нажатых клавиш
Отследить нажатие CTRL, SHIFT и ALT можно также другими способами (данный способ необходим чтобы отследить комбинации).
Например, отследить нажатие CTRL можно следующим образом:
document.addEventListener("keydown", function (e) < if (e.ctrlKey) < console.log("Был нажат CTRL"); document.getElementById("btnClick").textContent = "CTRL"; >>);
Используя всю ранее полученную информацию, определим нажатую комбинацию клавиш, например, CTRL + F5 :
document.addEventListener("keydown", function (e) < e.preventDefault(); if (e.ctrlKey && event.key == "F5") < console.log("Была нажата комбинация клавиш CTRL + F5"); >>);
Как вы могли заметить, обращаться к клавишам в JavaScript можно несколькими способами. Например, следующие строки кода позволяют нам получить один и тот же результат:
event.key == "F5" аналогично e.keyCode == 116
Мы рассмотрели, как получить информацию о нажатой клавише на клавиатуре. Теперь давайте рассмотрим, как обработать события мыши.
Информация о нажатой кнопке мыши JavaScript
Рассмотрим, как определить какая кнопка мыши нажимается над объектом: левая кнопка, правая или дабл клик.
Выполнение кода при клике левой кнопкой мыши:
document.querySelector(selector).onclick = function (e) < if (e.which == 1) < console.log("Нажата левая кнопка мыши"); >>
Выполнение кода при клике правой кнопкой мыши:
document.querySelector(selector).oncontextmenu = function (e)
Выполнение кода при двойном клике по кнопке:
document.querySelector(selector).ondblclick = function ()
Надеюсь, вам понравилась данная информация. Если вам интересна тема web-разработки, то можете следить за выходом новых статей в Telegram.