Keyboard keydown and keyup
JavaScript Keyboard: keydown and keyup
This chapter is dedicated to the study of keyboard, along with its keydown and keyup events, and their usage in JavaScript. (本章专门讨论键盘及其按键和按键事件的研究,以及它们在JavaScript中的使用。)
As a rule, a keyboard event is generated by pressing a key: no matter it’s a symbol key or a special key, such as Shift, Ctrl, and more.
Before getting to the keyboard, please consider that there are other ways of inputting on modern devices. For instance, speech recognition or copy/paste using the mouse. (在使用键盘之前,请考虑在现代设备上还有其他输入方式。例如,语音识别或使用鼠标复制/粘贴。)
In case you intend to track any input into the <input> field, then keyboard events are not enough. Another event called input is used for tracking changes of an input field by any means.
In general, keyboard events are used when there is an intention of handling keyboard actions (including virtual keyboard). For example, for reacting to arrow keys Up and Down or hotkeys ( key combinations are also counted). (一般来说,当有处理键盘动作(包括虚拟键盘)的意图时,使用键盘事件。例如,对向上和向下箭头键或热键做出反应(键组合也被计算在内)。)
Teststand
Teststand (测试台)
If you want to understand the keyboard events better, you can use the following test stand:
<!DOCTYPE html>
<html>
<head>
<title>Title of the Document</title>
<style>
#keyInput {
font-size: 100%;
box-sizing: border-box;
width: 90%;
border: 1px solid green;
}
#area {
width: 90%;
box-sizing: border-box;
height: 250px;
border: 1px solid green;
display: block;
}
form label {
display: inline;
white-space: nowrap;
}
</style>
</head>
<body>
<form id="form" onsubmit="return false">
<p>Focus on the input field and press a key.</p>
<input type="text" placeholder="Press keys here" id="keyInput">
<textarea id="area"></textarea>
<input type="button" value="Clear textarea" onclick="area.value = ''" />
<div>
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>
</div>
</form>
<script>
keyInput.onkeydown = keyInput.onkeyup = keyInput.onkeypress = handle;
let lastTime = Date.now();
function handle(e) {
if(form.elements[e.type + 'Ignore'].checked) return;
let text = e.type +
' key=' + e.key +
('key =' + e.key +)
' code=' + e.code +
('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)
(area.value + =新数组(81))
.join('-') + '\n';
}
lastTime = Date.now();
area.value += text;
if(form.elements[e.type + 'Stop'].checked) {
e.preventDefault();
}
}
</script>
</body>
</html>
Keydown and Keyup
Keydown and Keyup (KEYDOWN和KEYU)
The keydown and keyup events occur whenever the user presses a key. The keydown happens at the moment the user presses the key down. It repeats as long as the user keeps it down. The keyup event happens when the user releases the key after the default action has been performed. (每当用户按下键时,就会发生键下和键上事件。下键发生在用户按下键的时刻。只要用户保持低调,它就会重复。当用户在执行默认操作后释放密钥时,会发生keyup事件。)
Event.code and Event.key
The key property of the event object allows getting the character, while the code property - the “physical key code”. (事件对象的key属性允许获取字符,而code属性- “物理密钥代码”。)
For instance, the same “S” can be pressed both with the Shift button or without. It will give different characters: lowercase z and uppercase Z.
The event.key is the character itself: hence, it will be different.
In case the user works with different languages, then switching to another language will bring a completely different character instead of “S”. It will be the value of the event.key, while event.code is constantly the same. (如果用户使用不同的语言,那么切换到另一种语言将带来完全不同的字符,而不是“S”。这将是event.key的值,而event.code始终相同。)
An important thing to remember: KeyS and keyS are not the same. The first letter of Key should be uppercase. So, event.code==“keyZ” will cause an error. Let’s consider a case where a key doesn’t give a character. For example, Shift or F1. For these types of keys, event.key is almost the same as event.code. The event.code indicates exactly which key is pressed. For instance, almost all the keyboards have two Shift keys: on the right and the left side. The event.code specifies, which of them is pressed, and event.key tells you what key it is ( in this case, “Shift”).
Imagine handling a hotkey Ctrl+Z (for Mac it will be Cmd+Z). For most text editors, it provides an “Undo” action. It is possible to set a listener on keydown and check the pressed key. But, a dilemma appears here: should you check the event.key or event.code?
On the one hand, event.key is considered a character, it may change depending on the language. In case the user has different languages in OS and switches between them, the same key will give different characters. You, it is better to check event.code, like here:
<!DOCTYPE html>
<html>
<head>
<title>Title of the Document</title>
</head>
<body>
<script>
document.addEventListener('keydown', function(event) {
if(event.code == 'KeyZ' && (event.ctrlKey || event.metaKey)) {
alert('Undo!')
(alert ('撤消!'))
}
})
</script>
</body>
</html>
On the other hand, a problem exists with event.code. The same key can have different characters for different keyboard layouts. (另一方面, event.code存在问题。同一个键对于不同的键盘布局可以有不同的字符。)
Auto-repeat
Auto-repeat (自動重複)
When any key is being pressed for a long enough time, it gets “auto-repeating”. The keydown event happens again and again, and when it is released, the keyup is got. So, it is typical to have many keydowns and only one keyup. (当按下任何键足够长的时间时,它会“自动重复”。keydown事件一次又一次地发生,当它被释放时, keyup被获取。因此,通常会有多个按键,但只有一个按键。)
For events that happen by auto-repeat, the event.repeat property is set to true. (对于通过自动重复发生的事件, event.repeat属性设置为true。)
Default Actions
Default Actions (设置默认动作)
There can be different default actions. It’s because many possible things can be initiated by the keyboard, as described below:
A character comes out on the screen. (-一个角色出现在屏幕上。)
A character is deleted with the Delete key. (-使用Delete键删除字符。)
The scrolling of the page with the PageDown key. (-使用PageDown键滚动页面。)
Opening of the “Save Page” dialog by Ctrl+S. (-通过Ctrl + S打开“保存页面”对话框。)
If you prevent the default action on keydown, it may cancel most of them, except for the OS-based specific keys. For instance, Alt+F4 closes the current browser window on Windows. And, in JavaScript, no way exists to stop it by preventing the default action. (如果您禁止在键盘上执行默认操作,则可能会取消其中的大部分操作,但基于操作系统的特定键除外。例如, Alt + F4关闭Windows上的当前浏览器窗口。而且,在JavaScript中,没有办法通过阻止默认操作来阻止它。)
Let’s check out an example where the <input> expects a phone number, not accepting keys except digits, such as +, - or ():
<!DOCTYPE html>
<html>
<head>
<title>Title of the Document</title>
</head>
<body>
<script>
function checkedPhoneKey(key) {
return(key >= '0' && key <= '9') || key == '+' || key == '(' || key == ')' || key == '-';
}
</script>
<input onkeydown="return checkedPhoneKey(event.key)" placeholder="Phone number" type="tel">
</body>
</html>
Also, take into account that special keys, like Backspace, Left, Right, Ctrl+V will not work in such an output. That is the side-effect of the checkedPhoneKey strict filter. (此外,请考虑特殊键,如Backspace、Left、Right、Ctrl + V将无法在此类输出中工作。这是checkedPhoneKey严格过滤器的副作用。)
Let’s consider another example, where arrows and deletion works pretty well:
<!DOCTYPE html>
<html>
<head>
<title>Title of the Document</title>
</head>
<body>
<script>
function checkedPhoneKey(key) {
return(key >= '0' && key <= '9') || key == '+' || key == '(' || key == ')' || key == '-' ||
key == 'ArrowLeft' || key == 'ArrowRight' || key == 'Delete' || key == 'Backspace';
}
</script>
<input onkeydown="return checkedPhoneKey(event.key)" placeholder="Phone number" type="tel">
</body>
</html>
However, you can still add anything by applying a mouse and right-click + Paste. Therefore, the filter is not 100% reliable. There is an alternative means: tracking the input event, which triggers after any modification. There, you have the option of checking the new value and highlighting/modifying it whenever it’s not valid.
Legacy
Legacy (继承)
Previously, there was a keypress event, along with keyCode, charCode, which properties of the event object. (以前,有一个keypress事件,以及keyCode、charCode ,它们是事件对象的属性。)
Anyway, they caused so many incompatibilities that developers started deprecating all of them and making new, modern events ( described above). Of course, the old code still works but there is no use in them. (无论如何,它们引起了如此多的不兼容性,以至于开发人员开始弃用它们并制作新的现代事件(如上所述)。当然,旧代码仍然有效,但没有用。)
Summary
Summary (概要)
Pressing any key always creates a keyboard event, be it special keys or symbol keys. The exception is the Fn key, which at times is presented on a laptop keyboard. No keyboard event exists for it, as it’s often performed at a lower level than OS. (按任何键都会创建一个键盘事件,无论是特殊键还是符号键。唯一的例外是Fn键,有时会出现在笔记本电脑键盘上。它不存在键盘事件,因为它通常在比操作系统更低的级别执行。)
The keyboard events are keydown and keyup. The first one triggers on pressing the key down, the second one- on releasing the key. (键盘事件包括键盘下键和键盘上键。第一个在按下键时触发,第二个在释放键时触发。)
The primary keyboard event properties are the following:
code: it is the key code ( for example, “KeyA”), specific to the key location on the keyboard.
key: the character (“A”, “a”) for non-character keys. Normally, its value is equivalent to the value of the code.