深入事件

您所在的位置:网站首页 Java键盘事件处理方法 深入事件

深入事件

2023-03-19 08:05| 来源: 网络整理| 查看: 265

试验台keydown 和 keyupevent.code 和 event.key自动重复默认行为遗留问题总结练习题问题一、扩展热键答案一、扩展热键

原文链接:http://javascript.info/keyboard-events,translate with ❤️ by zhangbao.

在深入键盘事件之前,需要注意的是,还有其他的“输入”方式。例如:在手机设备上可以使用语音识别,或者用鼠标复制/粘贴进行输入。

因此,如果我们想要追踪 输入框,仅使用键盘事件是不够的。有一个叫 input 事件可以观察到任何情境下的 输入框里值的改变,有时它可能才是更好的选择。我们会在后面的《事件:change、input、cut、copy 和 paste》一章中介绍。

键盘事件用于处理键盘操作(虚拟键盘也包括在内)。例如,响应箭头按键 Up、Down 或者热键(包括组合键)。

试验台

为了更好地理解键盘事件,可以点点下面的试验台。

在文本域中尝试不同的组合键查看效果。

keydown 和 keyup

keydown 事件在按下鼠标时触发;keyup 事件在释放鼠标时触发。

event.code 和 event.key

事件对象的 key 属性用来获得按键表示的字符, code 属性用来获得“物理按键码”。

例如,按下按键 Z 的同时,可以选择按下/不按下 Shift 键。如此一来,我们将得到两个不同的字符:大写的 Z 和小写的 z。

event.key 属性对应实实在在打印出来的那个字符,可能有所不同;但打印出的 event.code 值始终是一样的:

按键 event.key event.code Z z(小写的) KeyZ Shift+Z Z(大写的) KeyZ

对于不同语言的键盘,得到的 event.key 值可能就不是“Z”了,而 event.code 值始终是“KeyZ”。

“**KeyZ``”**和其他按键码

键盘上不同的按键有不同的按键码。按键码可参考《UI 事件码规范》:

例如:

字符键的键码值,是“Key”的形式:例如“KeyA”、“KeyB”等。

数字键的键码值,是“Digital”的形式:例如“Digital0”、“Digital1”等。

其他按键的键码值按照名字的不同而不同:例如“Enter”、“Backspace” 和“Tab”等。

有几种常规键盘布局,规范为每种布局都指定了对应的按键代码。

请参阅《规范的字母数字部分》以获得更多按键码信息。

注意**大小写:是“**KeyZ**”,不是“****keyZ**”

虽然很明显,但还是经常会犯错的地方。

注意,是“KeyZ”,不是“keyZ”!像 event.code === "keyZ" 这种检查是无效的。 “Key”必须是首字母大写的形式。

如果一个按键不代表任何字符呢?例如,Shift、F1 或其他一些,对于这类按键,event.key 与 event.code 值基本一致。

按键 event.key event.code F1 F1 F1 Backspace Backspace Backspace Shift Shift ShiftRight 或 ShiftLeft

请注意,event.code 的值能让我们确定按下的是哪个按键。例如,大多数的键盘有两个 Shift 按键:左边一个、右边一个。event.code 就能告诉我们按下的是哪一个,event.key 则强调被按下按键的含义“Shift”。

如果需要处理热键:比如 Ctrl+Z(对应 Mac 上的 Cmd+Z)。许多文本编辑器绑定的默认操作是“撤销”。我们可以用 keydown 事件监听哪个按键被按下了——监测什么时候我们使用热键了。

请回答一个问题,在监听器中,我们应该检查 event.key 的值还是 event.code 的值呢?

请停下来想想。

……

想到了吗?

如果你已经理解了前面所说的,答案很明显,应该使用 event.code 而不是 event.key。因为 event.key 的值依赖语言环境或 CapsLock 按键是否开启,而 event.code 的值总是一致的,是于键盘上的按键唯一绑定的。

document.addEventListener('keydown', function (event) { if (event.code === 'keyZ' && (event.ctrlKey || eventaKey)) { alert('撤销'); }});

自动重复

如果一个按键长时间按下不释放,就会重复触发 keydown 事件;当释放按键时,触发一次 keyup 事件。所以结果会看到触发许多的 keydown 事件和一个 keyup 事件。

所有重复 keydown 事件的事件对象的 event.repeat 属性值都为 true。

默认行为

默认行为会有所不同,因为键盘操作可能会启动许多可能的行为。

例如:

出现一个字符(最明显的输出了)。

删除一个字符(按下 Delete 按键)。

滚动页面(按下 PageDown 按键)。

浏览器打开“保存”页面对话框(Ctrl+S)。

……

阻止 keydown 事件的默认行为可以取消大多数(除个别操作系统级的快捷键外)上述行为的发生 。例如,Windows 系统里的 Alt+F4 会关闭当前浏览器窗口,这是使用 JavaScript 无法阻止的行为。

下例中, 限制只能输入手机号码,不接受数字、+、() 和 - 外的其他符号:

function checkPhoneKey(key) { return (key >= '0' && key

需要注意的是,在输入框中按下像 Backspace、Left、Right 和 Ctrl+V 等这样特殊的按键也变失效了,这是过滤算法 checkPhoneKey 带来的副作用。

我们放松一下规则:

function checkPhoneKey(key) { return (key >= '0' && key

现在箭头按键和删除按键都可以使用了。

但是我们仍然可以通过鼠标右键粘贴输入文本,所以这也不是百分之百可信赖的。我们可以先让它这样,因为多数场景下都是可行的。另一个可选方案是检查 input 事件,这个事件会在每次输入框内容修改后触,我们可以在处理器中检查新的值,无效的话就修改它。

遗留问题

过去还会使用 keypress 事件,还有事件对象上的 keyCode、charCode 和 which 属性。

因为这些事件/事件属性并不是浏览器全兼容的,标准开发人员决定弃用它们。旧代码仍然有效,是因为浏览器还在支持它们,但是完全不需要再使用它们了。

曾几何时,本章中包含了对它们的详细描述,但现在我们可以忘记它们了。

总结

按下按键(可能是一个符号按键或是像 Shift、Ctrl 这样的特殊按键)会触发键盘事件。唯一的例外是有时出现在笔记本键盘上的 Fn 键,它没有键盘事件,因为它通常在比操作系统更低的级别上实现的。

键盘事件:

keydown——按下鼠标时触发(按住不放则会重复触发)

keyup——释放鼠标时触发。

主要的键盘事件对象属性:

code—— “按键码”(比如“KeyA”、“ArrowLeft”等),表示按键在键盘上的物理位置。

key——字符(比如“A”、“a”等),对于非字符按键,值通常跟 code 一致。

过去,键盘事件有时用于跟踪表单字段中的用户输入。这并不可靠,因为输入有多种方式。我们可以使用 input/change 事件处理用户输入(在《事件:change、input、cut、copy 和 paste》一章中讲到)。它们会在输入值改变后触发,包括鼠标或语音识别的输入。

当我们明确使用键盘操作的时候,才去使用键盘事件。例如,响应热键和特殊按键的操作。

练习题

问题

一、扩展热键

创建一个函数 runOnKeys(func, code1, code2, ... code_n) 仅在同时按下按键码 code1, code2, … code_n 时,才去执行回调函数 func。

例如下面代码里,仅在同时按下“Q”和“W”的时候(所有语言环境下,不管是否开启 CapsLock 键),调用 alert:

runOnKeys( () => alert("Hello!"), "KeyQ", "KeyW");

答案

一、扩展热键

我们会用到两个事件处理器:document.onkeydown 和 document.onkeyup。

集合 pressed 中保存现在按下的按键。

第一个处理器用来添加按键,第二个处理器用来删除按键。每次 keydown 的时候,我们就检查下是否按下了所有想要按下的按键,如果是的话,就执行回调函数。

function runOnKeys(func, ...codes) { let pressed = new Set(); document.addEventListener('keydown', function(event) { pressed.add(event.code); for (let code of codes) { // 是否按下了所有想要按下的按键 if (!pressed.has(code)) { return; } } // 好的,都按下了 // 在 alert 的时候,如果用户释放了按键 // JavaSript 不会接收到"keyup"事件 // pressed 集合里仍然保留所有按下的按键信息 // 为了避免"粘性"按键,我们重置了状态(清空了按键集合) // 如果用户想要再一次执行热键回调,就需要再一次全部按下按键 pressed.clear(); func(); }); document.addEventListener('keyup', function(event) { pressed.delete(event.code); });}

(完)



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3