https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
在W3School上,这个事实被淡化了,只有一个侧面说明说.keyCode
仅提供兼容性,并且DOM事件规范的最新版本建议使用.key
属性。问题是,浏览器不支持.key
,那么我们应该使用什么?我有什么遗漏的吗?https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
在W3School上,这个事实被淡化了,只有一个侧面说明说.keyCode
仅提供兼容性,并且DOM事件规范的最新版本建议使用.key
属性。问题是,浏览器不支持.key
,那么我们应该使用什么?我有什么遗漏的吗?例如,如果您想检测是否单击了“Enter”键:
可以使用以下代码:
event.keyCode === 13
像这样去做
event.key === 'Enter'
event.keyCode === 27
翻译为 event.key === 'Escape'
。 - Gil Epshtainevent.keyCode === 13
修改为 event.key === 'Enter'
将取消对数字键盘按键的支持。如果要同时支持两种方式,请使用以下代码:event.key === 'Enter' || event.key === 'NumpadEnter'
或者更好的选择是:['Enter', 'NumpadEnter'].includes(event.key)
- Austin Arnett你可以按照你分享的链接上所写的三种方法来处理它。
if (event.key !== undefined) {
} else if (event.keyIdentifier !== undefined) {
} else if (event.keyCode !== undefined) {
}
如果你想要跨浏览器支持,那么你应该考虑这些内容,这是正确的方式。
如果你实现类似这样的东西,它可能会更容易。
var dispatchForCode = function(event, callback) {
var code;
if (event.key !== undefined) {
code = event.key;
} else if (event.keyIdentifier !== undefined) {
code = event.keyIdentifier;
} else if (event.keyCode !== undefined) {
code = event.keyCode;
}
callback(code);
};
event.key
是一个字符串,而 event.keyCode
是一个数字,对吧?考虑到它们甚至没有相同的类型,它们怎么可能有相同的语义呢?或者你是指 event.code
吗? - bluenote10简述:建议您使用新的event.key
和event.code
属性而非之前的遗留属性。IE和Edge支持这些属性,但尚不支持新的键名。对于它们,有一个小型填充程序可以使它们输出标准的键名/代码:
https://github.com/shvaikalesh/shim-keyboard-event-key
我查找了同样MDN警告的原因,发现 keyCode
的问题更为明显:
使用keyCode
的问题在于,非英语键盘可能会产生不同的输出,即使是具有不同布局的键盘也会产生不一致的结果。此外,还有以下情况:
如果您阅读W3C规范:https://www.w3.org/TR/uievents/#interface-keyboardevent
实际上,keyCode和charCode在不同平台甚至同一操作系统的不同实现或使用不同本地化时存在不一致性。
它详细描述了keyCode
的问题:https://www.w3.org/TR/uievents/#legacy-key-attributes
这些功能从未被正式指定,当前的浏览器实现在很多方面存在不同。大量遗留内容(包括脚本库)依赖于检测用户代理并相应地采取行动,意味着任何试图形式化这些遗留属性和事件的尝试都会冒险破坏与修复/启用同样数量的内容。此外,这些属性不适合国际使用,也不能解决辅助功能问题。
因此,在确定了为什么要替换旧的keyCode之后,让我们看一下今天您需要做什么:
key
和code
)。KeyboardEvent.code
。此外,key
和code
的值也取决于浏览器。这两个问题都使得在实际应用中使用key
和code
变得不切实际。 - John Slegerskey
还是 code
?通常这是一个物理键,但也可能取决于 Num Lock 和布局...最佳实践是什么? - Jake除了所有的keyCode、which、charCode和keyIdentifier都已被废弃:
charCode
和 keyIdentifier
是非标准特性。
keyIdentifier
自 Chrome 54 和 Opera 41.0 开始被移除。
在 Firefox 上,keyCode
在按下普通字符时返回 0。
readonly attribute DOMString key
保存键按下时对应的关键属性值
截至本文撰写时,key
属性已被所有主要浏览器支持: Firefox 52、Chrome 55、Safari 10.1、Opera 46。但是Internet Explorer 11存在以下问题:非标准的键标识符和AltGraph不正确的行为。更多信息
如果这很重要或者需要向后兼容,则可以使用功能检测,如下面的代码:
请注意:key
值与keyCode
或which
属性不同,因为它包含键的名称而不是其代码。如果您的程序需要字符代码,则可以使用charCodeAt()
。对于单个可打印字符,您可以使用charCodeAt()
;如果您处理的是包含多个字符的键值,例如ArrowUp,则可能正在测试特殊键并相应地采取措施。因此,请尝试实现一个表格,其中包含键的值及其相应的代码charCodeArr["ArrowUp"]=38
、charCodeArr["Enter"]=13
、charCodeArr[Escape]=27
等等,请查看键值及其相应的代码
if(e.key!=undefined){
var characterCode = charCodeArr[e.key] || e.key.charCodeAt(0);
}else{
/* As @Leonid suggeted */
var characterCode = e.which || e.charCode || e.keyCode || 0;
}
/* ... code making use of characterCode variable */
也许你想考虑向前兼容,即在可用的情况下使用旧属性,只有在这些属性被弃用后才切换到新属性:
if(e.which || e.charCode || e.keyCode ){
var characterCode = e.which || e.charCode || e.keyCode;
}else if (e.key!=undefined){
var characterCode = charCodeArr[e.key] || e.key.charCodeAt(0);
}else{
var characterCode = 0;
}
charCodeArr
函数不存在。此外,charCodeAt
对于所有值的e.key
都不起作用。例如,对于“Enter”/“Return”键,e.key
属性的值为“Enter”,并且执行该字符串的charCodeArr
返回值为69
(这是字符E
的ASCII代码)。 - John SlegersMDN已经提供了解决方案:
https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode
window.addEventListener("keydown", function (event) {
if (event.defaultPrevented) {
return; // Should do nothing if the default action has been cancelled
}
var handled = false;
if (event.key !== undefined) {
// Handle the event with KeyboardEvent.key and set handled true.
} else if (event.keyIdentifier !== undefined) {
// Handle the event with KeyboardEvent.keyIdentifier and set handled true.
} else if (event.keyCode !== undefined) {
// Handle the event with KeyboardEvent.keyCode and set handled true.
}
if (handled) {
// Suppress "double action" if event handled
event.preventDefault();
}
}, true);
建议使用键值(key)而不是按键码(keyCode),如果失败了再使用按键码(keyCode)。然而这还不够,因为这些属性中的值不兼容。问题在于新的键值(key)包含控制键的字符串,例如:ArrowUp,但按键码(keyCode)只包含简单的代码。
String.fromCharCode(event.keyCode)
输入非可打印字符会导致问题,以下是可打印字符的解决方案:
element.keydown((event) => {
var symbolPressed;
//cross browser
if (event.key !== undefined) {
symbolPressed = event.key; //Here control characters represented as String like: ArrowUp
if (symbolPressed.length > 1) return; //filter out control characters
} else if (event.keyCode !== undefined) {
symbolPressed = String.fromCharCode(event.keyCode); //Here control chars represented as one char string
}
//Update this regex if you need other characters
if (!symbolPressed.match(/[A-z0-9\s]/)) return;
console.log(symbolPressed);
});
如果您需要非可打印的控制字符,您需要相应地更新条件和正则表达式。
使用 onkeypress 和 onkeydown 事件来获取 event.which,它可以切换 [字符代码] 或 [键代码]
function myKey(event){
var keycode = event.keyCode; //key code variant 1, not recomendate
var keywhic = event.which; //key code variant 2, nice worked
var unicode = event.key; //string name code, nice worked
var chacode = event.charCode; //works onkeypress="myKey(event)"
var metakey = event.metaKey; //true false, winKey or macComand
document.getElementById("demo").innerHTML = keycode+" "+keywhic+" "+unicode+" "+chacode+" "+metakey;
}
<!DOCTYPE html>
<html>
<body onkeydown="myKey(event)"> <!--onkeypress="myKey(event)"-->
<h1 id="demo">Keyboard Buttons click me and test the keyboard</h1>
<script>
//function myKey(event){
//paste code
//}
</script>
</body>
</html>
您可以使用
parseInt(event.key, radix: 10)
.key
在所有主流浏览器中都有支持。详情请参考 https://developer.mozilla.org/zh-CN/docs/Web/API/KeyboardEvent/key#Browser_compatibility - sbolelevent.key
。 - Herohtar