Javascript 在 jQuery 中的单个按键事件上检测多个键
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10655202/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Detect multiple keys on single keypress event in jQuery
提问by remarsh
Is it at all possible to combine a mixture of keypress' to fire a single event?
是否有可能结合按键'的混合来触发单个事件?
$(document).keyup(function(e){
if (e.keyCode == 68 && e.keyCode == 69 && e.keyCode == 86) {
alert('oh hai');
}
});
I've tried it in Chrome but the event doesn't fire.
我已经在 Chrome 中尝试过,但该事件没有触发。
Call me crazy but I am writing a Chrome extension and want to push D+E+Vkeys together to force it into a hidden developer mode.
叫我疯了,但我正在编写一个 Chrome 扩展程序,并希望将D+ E+V键推到一起以强制它进入隐藏的开发人员模式。
回答by T.J. Crowder
If you want to detect that the d, e, and vkeys were all down at the same time, you have to watch both keydown
and keyup
and keep a map of the ones that are down. When they're all down, fire your event.
如果要检测的d,e和v钥匙都在同一时间全部下来,你得看都keydown
和keyup
并保持地图为down的那些的。当它们全部关闭时,触发您的事件。
For example: Live copy| source
var map = {68: false, 69: false, 86: false};
$(document).keydown(function(e) {
if (e.keyCode in map) {
map[e.keyCode] = true;
if (map[68] && map[69] && map[86]) {
// FIRE EVENT
}
}
}).keyup(function(e) {
if (e.keyCode in map) {
map[e.keyCode] = false;
}
});
I assume you don't care what order they're pressed down in (as that would be a pain to reliably press) as long as they're all down at the same time at some point.
我假设您不在乎按什么顺序按下它们(因为可靠地按下会很痛苦),只要它们在某个时间点同时按下即可。
回答by Parth Thakkar
Similar to Vega's...but simpler
类似于 Vega 的……但更简单
var down = {};
$(document).keydown(function(e) {
down[e.keyCode] = true;
}).keyup(function(e) {
if (down[68] && down[69] && down[86]) {
alert('oh hai');
}
down[e.keyCode] = false;
});?
回答by gplumb
Perhaps a simpler key combination would be easier?
也许更简单的组合键会更容易?
How about something like Shift + Alt + D? (You probably shouldn't use the Control key because most browsers already interpret Ctrl+D in one way or another)
像 Shift + Alt + D 这样的东西怎么样?(您可能不应该使用 Control 键,因为大多数浏览器已经以一种或另一种方式解释了 Ctrl+D)
The code for this would be something like this:
代码如下:
if(e.shiftKey && e.altKey && e.keyCode == 68)
{
alert('l33t!');
}
回答by Smelino
I have answer from T.J. Crowderin plain javascript for someone who would want to avoid Jquery.
对于想要避免使用 Jquery 的人,我从TJ Crowder那里得到了纯 javascript 的回答。
//A W S D simultaneously
var map = {65: false, 87: false, 83: false, 68: false};
document.body.addEventListener('keydown', function (e) {
var e = e || event; //to deal with old IE
if (e.keyCode in map) {
map[e.keyCode] = true;
if (map[65] && map[87]) {
console.log('up left');
}else if (map[83] && map[68]) {
console.log('down right');
}else if (map[87] && map[68]) {
console.log('up right');
}else if (map[83] && map[65]) {
console.log('down left');
}
}
});
document.body.addEventListener('keyup', function (e) {
if (e.keyCode in map) {
map[e.keyCode] = false;
}
});
回答by Nemo-Omen
I tried the three top answers (as of this post), and none of them worked for me. They didn't reset the keys.
我尝试了三个最重要的答案(截至本文),但没有一个对我有用。他们没有重置钥匙。
If it took 3 keys fire the script, after firing it once - pressing any one of the 3 keys would fire it again.
如果需要 3 个键来触发脚本,则在触发一次后 - 按 3 个键中的任何一个都会再次触发它。
I just wrote this script and it's working very well. It uses Shift+S to fire, but you can easily change that. It resets after pressing the combination.
我刚刚写了这个脚本,它运行得很好。它使用 Shift+S 来触发,但您可以轻松更改它。按下组合键后它会重置。
var saveArray = new Array();
saveArray[0] = false;
saveArray[1] = false;
$(document).ready(function(){
$(document).keydown(function (f){
if (f.keyCode == 16) {
saveArray[0] = true;
}
});
$(document).keyup(function (g){
if(g.which == 16){
saveArray[0] = false;
}
});
$(document).keydown(function (h){
if (h.keyCode == 83) {
saveArray[1] = true;
if(saveArray[0] == true && saveArray[1] == true){
saveArray[0] = false;
saveArray[1] = false;
keypressSaveFunction();
}
}
});
$(document).keyup(function (i){
if (i.which == 83) {
saveArray[1] = false;
}
});
});
function keypressSaveFunction(){
alert("You pressed Shift+S");
}
Fiddle: http://jsfiddle.net/9m8yswwo/13/
回答by Micha? Per?akowski
A bit more modern solution, takes advantage of arrow functionsand rest parameters:
const multipleKeypress = (function($document) {
// Map of keys which are currently down.
const keymap = {}
// Update keymap on keydown and keyup events.
$document.on(
"keydown keyup"
// If the key is down, assign true to the corresponding
// propery of keymap, otherwise assign false.
,event => keymap[event.keyCode] = event.type === "keydown"
)
// The actual function.
// Takes listener as the first argument,
// rest of the arguments are key codes.
return (listener, ...keys) =>
$document.keydown(() => {
// Check if every of the specified keys is down.
if (keys.every(key => keymap[key]))
listener(event)
})
// Pass a jQuery document object to cache it.
}($(document)))
// Example usage:
multipleKeypress(() => console.log("pressed"), 68, 69, 86)
// Automatically focus the snippet result
window.focus()
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Try pressing <kbd>d</kbd>, <kbd>e</kbd> and <kbd>v</kbd> at once.</p>
回答by FishBasketGordo
You would need to capture the three key events separately and fire your action only after the third one.
您需要分别捕获三个关键事件,并仅在第三个事件之后触发您的操作。
var keys = {
d: { code: 100, pressed: false, next: 'e' },
e: { code: 101, pressed: false, next: 'v' },
v: { code: 118, pressed: false, next: 'd' }
},
nextKey = 'd';
$(document).keypress(function(e) {
if (e.keyCode === keys[nextKey].code) {
keys[nextKey].pressed = true;
nextKey = keys[nextKey].next;
} else {
keys.d.pressed = false;
keys.e.pressed = false;
keys.v.pressed = false;
nextKey = 'd';
}
if (keys.d.pressed && keys.e.pressed && keys.v.pressed) {
alert('Entering dev mode...');
}
});?
There's a number of ways to do this of course. This example doesn't require you to hold the keys down simultaneously, just that you type them in order: dev.
当然,有很多方法可以做到这一点。此示例不要求您同时按住键,只需按顺序键入它们:dev。
If you used this, you might want to augment it to clear the pressed
flags after some time interval.
如果你使用了它,你可能想要增加它以pressed
在一段时间间隔后清除标志。
Here's a working example.
这是一个工作示例。
Disclaimer: I realize the original question said that the keys should be "pressed together". This is just an alternative as other answerers have already provided sufficient solutions for the keys being pressed together.
免责声明:我意识到原来的问题是说键应该“按在一起”。这只是一种替代方法,因为其他回答者已经为按键一起按下提供了足够的解决方案。
回答by Fabrizio Calderan
if I well understood : example fiddle, http://jsfiddle.net/gAtTk/(look at your js console)
如果我很好理解:示例小提琴,http: //jsfiddle.net/gAtTk/(看看你的 js 控制台)
this code will let you enter the word "dev
" (and in this example, at the end the event keyup
is removed)
此代码将让您输入单词“ dev
”(在此示例中,最后keyup
删除了事件)
(function(seq) {
var tmp = seq.slice();
$(document).on("keyup.entersequence", function(e){
if (!(e.keyCode === tmp.pop())) {
tmp = seq.slice();
}
else {
console.log(e.keyCode);
if (!tmp.length) {
console.log('end');
$(document).off("keyup.entersequence");
}
}
});
}([68,69,86].reverse()));
回答by kapsiR
You should use the keydown and keyup events, to handle more then one key "at the same time".
您应该使用 keydown 和 keyup 事件,以“同时”处理多个键。
input.on("keydown", function (e) {
if (e.which == 17) {
isCtrl = true; // Ctrl
return;
}
/* Ctrl and "c" */
if (isCtrl && e.which == 67) {
//some code
}
}).keyup(function (e) {
if (e.which == 17) {
isCtrl = false; // no Ctrl
}
});
回答by Yves-Richard HTH
Use this code to have an event triggered by multiple key presses + Timeout after 100ms to prevent mistypes. In this example : if A,Z,E are pressed within a time period of 100ms, the event will be triggered.
使用此代码在 100 毫秒后通过多次按键触发事件 + 超时以防止输入错误。在本例中:如果在 100ms 的时间段内按下 A、Z、E,将触发事件。
var map = {65:false,90:false,69:false}; //Modify keyCodes here
$(document).keydown(function(e){
console.log(e.keyCode);
map[e.keyCode] = e.keyCode in map ? true : map[e.keyCode] || false;
var result = Object.keys(map).filter(function(key){
return map[key];
}).length === Object.keys(map).length ? true : false;
if(result){
//Your event here
Object.keys(map).forEach(function(key){
map[key] = false;
});
}
setTimeout(function(){
map[e.keyCode] = false;
},100);
});