Javascript jQuery .keypress() 可以同时检测多个键吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4954403/
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
Can jQuery .keypress() detect more than one key at the same time?
提问by Chris Abrams
Is there a way for jQuery to detect that more than one key was pressed at the same time?
有没有办法让 jQuery 检测到同时按下了多个键?
Is there any alternative that allows for pressing two keys at the same time to be detected?
是否有任何替代方法可以检测到同时按下两个键?
回答by David Tang
In order to detect multiple keys being held down, use the keydown
and keyup
events.
为了检测被按住的多个键,请使用keydown
和keyup
事件。
var keys = {};
$(document).keydown(function (e) {
keys[e.which] = true;
});
$(document).keyup(function (e) {
delete keys[e.which];
});
I've put together a demo here: http://jsfiddle.net/gFcuU/. It's kind of fun, though I noticed my keyboard is only able to detect at most 6 keys.
我在这里整理了一个演示:http: //jsfiddle.net/gFcuU/。这很有趣,但我注意到我的键盘最多只能检测 6 个键。
回答by jAndy
It depends. For "normal" keys, that means Non- Shift, Ctrl, ALT, (CMD), the answer is no, the event handler will catch/fire in a queue, one after another.
这取决于。对于“正常”键,这意味着非Shift,Ctrl,ALT,( CMD),答案是否定的,该事件处理程序将赶上/火在队列中,一个接一个。
For the modifier keys I mentioned above, there is a property on the event object.
对于我上面提到的修饰键,事件对象上有一个属性。
Example:
例子:
$(document).bind('keypress', function(event) {
if( event.which === 65 && event.shiftKey ) {
alert('you pressed SHIFT+A');
}
});
Other propertys are:
其他属性是:
event.ctrlKey
event.altKey
event.metaKey
event.ctrlKey
event.altKey
event.metaKey
回答by Robert Alex Matevish
If you just want to fire a handler when several keys are pressed in series, try something like:
如果您只想在连续按下多个键时触发处理程序,请尝试以下操作:
jQuery.multipress = function (keys, handler) {
'use strict';
if (keys.length === 0) {
return;
}
var down = {};
jQuery(document).keydown(function (event) {
down[event.keyCode] = true;
}).keyup(function (event) {
// Copy keys array, build array of pressed keys
var remaining = keys.slice(0),
pressed = Object.keys(down).map(function (num) { return parseInt(num, 10); }),
indexOfKey;
// Remove pressedKeys from remainingKeys
jQuery.each(pressed, function (i, key) {
if (down[key] === true) {
down[key] = false;
indexOfKey = remaining.indexOf(key);
if (indexOfKey > -1) {
remaining.splice(indexOfKey, 1);
}
}
});
// If we hit all the keys, fire off handler
if (remaining.length === 0) {
handler(event);
}
});
};
For instance, to fire on s-t,
例如,向 st 开火,
jQuery.multipress([83, 84], function () { alert('You pressed s-t'); })
回答by Hastig Zusammenstellen
Here's a jQuery solution based on Maciej's answer https://stackoverflow.com/a/21522329/
这是基于 Maciej 回答的 jQuery 解决方案https://stackoverflow.com/a/21522329/
// the array to add pressed keys to
var keys = [];
// listen for which key is pressed
document.addEventListener('keydown', (event) => {
if ($.inArray(event.keyCode, keys) == -1) {
keys.push(event.keyCode);
}
console.log('keys array after pressed = ' + keys);
});
// listen for which key is unpressed
document.addEventListener('keyup', (event) => {
// the key to remove
var removeKey = event.keyCode;
// remove it
keys = $.grep(keys, function(value) {
return value != removeKey;
});
console.log('keys array after unpress = ' + keys);
});
// assign key number to a recognizable value name
var w = 87;
var d = 68;
var s = 83;
var a = 65;
// determine which keys are pressed
document.addEventListener('keydown', (event) => {
if ($.inArray(w, keys) != -1 && $.inArray(d, keys) != -1) { // w + d
console.log('function for w + d combo');
} else if ($.inArray(s, keys) != -1 && $.inArray(a, keys) != -1) { // s + a
console.log('function for s + a combo');
}
})
fiddle demo
小提琴演示
回答by Jacob Relkin
Nope. keypress
will fire for every individual key that is pressed - except for modifier keys such as CTRL, ALT and SHIFT, you cancombine them with other keys, so long as it is only one other key.
不。keypress
将针对每个被按下的单个键触发 - 除了 CTRL、ALT 和 SHIFT 等修饰键之外,您可以将它们与其他键组合,只要它只是一个其他键。
回答by Maciej Paprocki
As my gist expired ( no one was using it :( ) I decided to update the answer with more 2017 solution. Check below.
随着我的要点过期(没有人使用它:()我决定用更多 2017 解决方案更新答案。检查下面。
You can use my plugin for jquery to detect shortcuts.
您可以使用我的 jquery 插件来检测快捷方式。
It basically cache's events and get what keys are pressed at the moment. If all the keys are pressed it fires function.
它基本上缓存的事件并获取此刻按下的键。如果按下所有键,则会触发功能。
https://github.com/maciekpaprocki/bindShortcut(expired!)
https://github.com/maciekpaprocki/bindShortcut(已过期!)
You have small explanation how to use it in readme file. Hope this helps. Feedback more than appreciated.
您对如何在自述文件中使用它有一些小说明。希望这可以帮助。反馈多于赞赏。
Edit 2017:
2017年编辑:
It's 2017 and we don't need jQuery plugins to solve stuff like that. In short you will need something like this:
现在是 2017 年,我们不需要 jQuery 插件来解决这样的问题。简而言之,您将需要这样的东西:
let pressed = {};
document.addEventListener('keydown', (event) => {
pressed[event.key] = true;
});
document.addEventListener('keyup', (event) => {
delete pressed[event.key];
});
//and now write your code
document.addEventListener('keydown', (event) => {
if(pressed[firstKey]&&pressed[secondKey]){
//dosomething
}
});
Older browsers might have some quirks, however from IE9 everything should work fine except of marginal amounts of OSs that don't support right event delegation (super old ubuntu etc.). There's no way to fix that in them as that's not the browser issue.
较旧的浏览器可能有一些怪癖,但是从 IE9 开始,除了不支持正确事件委托的少量操作系统(超级旧的 ubuntu 等)之外,一切都应该正常工作。没有办法解决这个问题,因为这不是浏览器问题。
There are some quirks in new macs connected to boolean keys like for example caps lock.
连接到布尔键的新 Mac 中有一些怪癖,例如大写锁定。
Read more: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names_and_Char_values
阅读更多:https: //developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names_and_Char_values
回答by y?lmaz
According to @David Tang's solution, here is a quick and dirty customization for capturing Shift+Ctrl+A combination:
根据@David Tang 的解决方案,这是一个用于捕获 Shift+Ctrl+A 组合的快速而肮脏的自定义:
var pressedKeys = {};
function checkPressedKeys() {
var shiftPressed=false, ctrlPressed=false, aPressed=false;
for (var i in pressedKeys) {
if (!pressedKeys.hasOwnProperty(i)) continue;
if(i==16){
shiftPressed=true;
}
else if(i==17){
ctrlPressed=true;
}
else if(i==65){
aPressed=true;
}
}
if(shiftPressed && ctrlPressed && aPressed){
//do whatever you want here.
}
}
$(document).ready(function(){
$(document).keydown(function (e) {
pressedKeys[e.which] = true;
checkPressedKeys();
});
$(document).keyup(function (e) {
delete pressedKeys[e.which];
});
});
回答by Fabio Sungurlian
If you're using esma6, you could do the following using sets.
如果您使用的是 esma6,则可以使用集合执行以下操作。
const KEYS = new Set();
$(document).keydown(function (e) {
KEYS.add(e.which);
if(KEYS.has(12) && KEYS.has(31)){
//do something
}
});
$(document).keyup(function (e) {
KEYS.delete(e.which);
});
And if you want the user to press them together, you can do:
如果您希望用户将它们按在一起,您可以执行以下操作:
const KEYS = new Set(); // for other purposes
const RECENT_KEYS = new Set(); // the recently pressed keys
const KEY_TIMELAPSE = 100 // the miliseconds of difference between keys
$(document).keydown(function (e) {
KEYS.add(e.which);
RECENT_KEYS.add(e.which);
setTimeout(()=>{
RECENT_KEYS.delete(e.which);
}, KEY_TIMELAPSE);
if(RECENT_KEYS.has(37) && RECENT_KEYS.has(38)){
// Do something
}
});
$(document).keyup(function (e) {
KEYS.delete(e.which);
RECENT_KEYS.delete(e.which);
});
Here is a codepen https://codepen.io/Programador-Anonimo/pen/NoEeKM?editors=0010
这是一个代码笔https://codepen.io/Programador-Anonimo/pen/NoEeKM?editors=0010