var map = {}; // You could also use an array
onkeydown = onkeyup = function(e){
e = e || event; // to deal with IE
map[e.keyCode] = e.type == 'keydown';
/* insert conditional here */
}
如果检查不同数量的组合(如CtrlShiftAltEnter和CtrlEnter),则放置较小的组合 after 较大的组合,否则较小的组合将覆盖较大的组合(如果它们足够相似) . 例:
// Correct:
if(map[17] && map[16] && map[13]){ // CTRL+SHIFT+ENTER
alert('Whoa, mr. power user');
}else if(map[17] && map[13]){ // CTRL+ENTER
alert('You found me');
}else if(map[13]){ // ENTER
alert('You pressed Enter. You win the prize!')
}
// Incorrect:
if(map[17] && map[13]){ // CTRL+ENTER
alert('You found me');
}else if(map[17] && map[16] && map[13]){ // CTRL+SHIFT+ENTER
alert('Whoa, mr. power user');
}else if(map[13]){ // ENTER
alert('You pressed Enter. You win the prize!');
}
// What will go wrong: When trying to do CTRL+SHIFT+ENTER, it will
// detect CTRL+ENTER first, and override CTRL+SHIFT+ENTER.
// Removing the else's is not a proper solution, either
// as it will cause it to alert BOTH "Mr. Power user" AND "You Found Me"
if(map[17] && map[13]){ // CTRL+ENTER
alert('Oh noes, a bug!');
}
// When you Press any key after executing this, it will alert again, even though you
// are clearly NOT pressing CTRL+ENTER
// The fix would look like this:
if(map[17] && map[13]){ // CTRL+ENTER
alert('Take that, bug!');
map = {};
}
// The bug no longer happens since the array is cleared
好的,所以你不要't always want to exit the function at that point. That'为什么 event.preventDefault() 功能在那里 . 它的作用是设置一个告诉内部标志的内部标志解释器到 not 允许浏览器运行其默认操作 . 之后,继续执行该功能(而 return 将立即退出该功能) .
document.body.onkeydown = function(ev){
// do some stuff
ev.preventDefault(); // cancels default actions
return false; // cancels this function as well as default actions
}
document.body.addEventListener("keydown", function(ev){
// do some stuff
ev.preventDefault() // cancels default actions
return false; // cancels this function only
});
Internet Explorer 's non-standard implementation, but this is beyond deprecated and doesn'中也有 attachEvent("onevent", callback) 甚至属于JavaScript(它属于一种叫做JScript的深奥语言) . 尽可能避免使用多语言代码符合您的最佳利益 .
document.onkeydown = keydown;
function keydown (evt) {
if (!evt) evt = event;
if (evt.ctrlKey && evt.altKey && evt.keyCode === 115) {
alert("CTRL+ALT+F4");
} else if (evt.shiftKey && evt.keyCode === 9) {
alert("Shift+TAB");
}
}
7
我用这种方式(必须检查哪里是按住Shift键):
// create some object to save all pressed keys
var keys = {
shift: false,
ctrl: false
};
$(document.body).keydown(function(event) {
// save status of the button 'pressed' == 'true'
if (event.keyCode == 16) {
keys["shift"] = true;
} else if (event.keyCode == 17) {
keys["ctrl"] = true;
}
if (keys["shift"] && keys["ctrl"]) {
$("#convert").trigger("click"); // or do anything else
}
});
$(document.body).keyup(function(event) {
// reset status of the button 'released' == 'false'
if (event.keyCode == 16) {
keys["shift"] = false;
} else if (event.keyCode == 17) {
keys["ctrl"] = false;
}
});
0
使keydown甚至调用多个函数,每个函数检查一个特定的键并适当地响应 .
document.keydown = function (key) {
checkKey("x");
checkKey("y");
};
document.body.addEventListener('keydown', keysDown(actions) );
function actions() {
// do stuff here
}
// simultaneous pressing Alt + R
function keysDown (cb) {
return function (zEvent) {
if (zEvent.altKey && zEvent.code === "KeyR" ) {
return cb()
}
}
}
9 回答
如果您了解这个概念,就可以轻松进行多次击键检测
我这样做的方式是这样的:
此代码非常简单:由于计算机一次只传递一次击键,因此会创建一个数组来跟踪多个键 . 然后可以使用该阵列一次检查一个或多个密钥 .
只是为了解释一下,假设您按下A和B,每个都会触发一个
keydown
事件,将map[e.keyCode]
设置为e.type == keydown
的值,其值为true或false . 现在map[65]
和map[66]
都设置为true
. 当你放开A
时,keyup
事件触发,导致相同的逻辑确定map[65]
(A)的相反结果,现在为假,但是因为map[66]
(B)仍然是"down"(它没有触发键盘事件),它仍然是真的 .通过这两个事件,
map
数组如下所示:你现在可以做两件事:
A) 当您想要快速找出一个或多个键码时,可以创建键 Logger (example)作为参考 . 假设您已经定义了一个html元素并使用变量
element
指向它 .注意:您可以通过
id
属性轻松获取元素 .这创建了一个html元素,可以使用
element
在javascript中轻松引用你甚至不必使用
document.getElementById()
或$()
来 grab 它 . 但为了兼容性,更广泛地推荐使用jQuery的$()
.只需确保脚本标记位于HTML正文之后 . Optimization tip :大多数大牌网站都将脚本标记 after 作为优化的正文标记 . 这是因为脚本标记会阻止其他元素加载,直到脚本完成下载 . 将其置于内容之前允许预先加载内容 .
B (which is where your interest lies) 您可以在
/*insert conditional here*/
的时间检查一个或多个密钥,举个例子:Edit :这不是重要的,所以你可以尝试这样的东西让眼睛更容易:
用法:
这是否更好?
(编辑结束)
此示例检查CtrlShiftA,CtrlShiftB和CtrlShiftC
就像那一样简单:)
注意事项
跟踪KeyCodes
作为一般规则,最好记录代码,特别是密钥代码(如
// CTRL+ENTER
),以便您记住它们是什么 .您还应该按照文档(
CTRL+ENTER => map[17] && map[13]
,NOTmap[13] && map[17]
)的顺序放置密钥代码 . 这样,当您需要返回并编辑代码时,您将不会感到困惑 .与if-else链相关的问题
如果检查不同数量的组合(如CtrlShiftAltEnter和CtrlEnter),则放置较小的组合 after 较大的组合,否则较小的组合将覆盖较大的组合(如果它们足够相似) . 例:
陷阱:“即使我没有按键,这个键组合也会继续激活”
处理警报或从主窗口获取焦点的任何事物时,您可能希望包含
map = []
以在条件完成后重置阵列 . 这是因为某些内容(如alert()
)将焦点从主窗口移开并导致'keyup'事件无法触发 . 例如:Gotcha:浏览器默认值
这是我发现的烦人的事情,包括以下解决方案:
问题:由于浏览器通常对键组合有默认操作(如CtrlD激活书签窗口,或者CtrlShiftC激活maxthon上的skynote),您可能还想在
map = []
之后添加return false
,因此当您的网站用户不会感到沮丧时"Duplicate File"函数,放在CtrlD上,代替书签 .如果没有
return false
,书签窗口会弹出,让用户感到沮丧 .返回声明(新)
好的,所以你不要't always want to exit the function at that point. That'为什么
event.preventDefault()
功能在那里 . 它的作用是设置一个告诉内部标志的内部标志解释器到 not 允许浏览器运行其默认操作 . 之后,继续执行该功能(而return
将立即退出该功能) .在决定是否使用
return false
或e.preventDefault()
之前,请先了解这一区别不推荐使用
event.keyCode
用户SeanVieira在评论中指出
event.keyCode
已被弃用 .在那里,他给出了一个很好的选择:
event.key
,它返回被按下的键的字符串表示,如A的"a"
或Shift的"Shift"
.我继续做了一个tool来检查所说的琴弦 .
element.onevent vs element.addEventListener
注册
addEventListener
的处理程序可以堆叠,并按注册顺序调用,而直接设置.onevent
则相当激进并覆盖您以前拥有的任何内容 ..onevent
属性似乎覆盖了所有内容,ev.preventDefault()
和return false;
的行为可能相当不可预测 .在任何一种情况下,通过
addEventlistener
注册的处理程序似乎更容易编写和推理 .Internet Explorer 's non-standard implementation, but this is beyond deprecated and doesn'中也有
attachEvent("onevent", callback)
甚至属于JavaScript(它属于一种叫做JScript的深奥语言) . 尽可能避免使用多语言代码符合您的最佳利益 .辅助类
为了解决混淆/抱怨,我写了一个"class"来做这个抽象(pastebin link):
这个类不会做任何事情,它不会处理每个可能的用例 . 我不是图书馆的人 . 但对于一般的交互式使用它应该没问题 .
要使用此类,请创建一个实例并将其指向要将键盘输入与之关联的元素:
这将做的是使用
#txt
(让's assume it' s为textarea)将新的输入侦听器附加到元素,并为键组合Ctrl+5
设置一个观察点 . 当Ctrl
和5
都关闭时,将传入您传入的回调函数(在本例中,是一个将"FIVE "
添加到textarea的函数) . 回调与名称print_5
相关联,因此要删除它,您只需使用:要从
txt
元素中分离input_txt
:这样,垃圾收集可以拾取对象(
input_txt
),如果它被丢弃,你将不会留下旧的僵尸事件监听器 .为了彻底,这里是对类的API的快速参考,以C / Java风格呈现,以便您知道它们返回什么以及它们期望的参数 .
Update 2017-12-02 为了响应将此发布到github的请求,我创建了一个gist .
Update 2018-07-21 我已经玩了一段时间的声明式编程,这种方式现在是我个人的最爱:fiddle,pastebin
一般来说,它会适用于你想要的情况(ctrl,alt,shift),但是如果你需要同时点击
a+w
,那么进入多方的方法就不会太难了 . -key的查找 .我希望这个彻底解释回答迷你博客很有帮助:)
您应该使用 keydown 事件来跟踪按下的键,并且您应该使用 keyup 事件来跟踪释放键的时间 .
看这个例子:http://jsfiddle.net/vor0nwe/mkHsU/
(更新:我在这里复制代码,以防jsfiddle.net保释:) HTML:
...和Javascript(使用jQuery):
在那个例子中,我正在使用一个数组来跟踪正在按下哪些键 . 在实际应用程序中,一旦释放了相关键,您可能需要
delete
每个元素 .请注意,虽然我在这个例子中使用了jQuery让自己变得简单,但在使用“原始”Javascript时,这个概念也同样适用 .
我用这种方式(必须检查哪里是按住Shift键):
使keydown甚至调用多个函数,每个函数检查一个特定的键并适当地响应 .
谁需要完整的示例代码 . 右左添加
如果按下其中一个键是Alt / Crtl / Shift,您可以使用此方法:
我试着在
keydown
上添加keypress
Event
处理程序 . 例如:这只是为了说明一种模式;我不会在这里详细介绍(尤其不是浏览器特定的level2
Event
注册) .请回复一下这是否有帮助 .
我知道,这不是最好的方式 .