admin管理员组文章数量:1136448
Is there a way for jQuery to detect that more than one key was pressed at the same time?
Is there any alternative that allows for pressing two keys at the same time to be detected?
Is there a way for jQuery to detect that more than one key was pressed at the same time?
Is there any alternative that allows for pressing two keys at the same time to be detected?
Share Improve this question edited Feb 10, 2011 at 7:26 Chris Abrams asked Feb 10, 2011 at 7:18 Chris AbramsChris Abrams 42.3k20 gold badges53 silver badges57 bronze badges9 Answers
Reset to default 78In order to detect multiple keys being held down, use the keydown
and keyup
events.
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.
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.
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');
}
});
Jsfiddle demo.
Other propertys are:
event.ctrlKey
event.altKey
event.metaKey
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,
jQuery.multipress([83, 84], function () { alert('You pressed s-t'); })
Nope. keypress
will fire for every individual key that is pressed - except for modifier keys such as CTRL, ALT and SHIFT, you can combine them with other keys, so long as it is only one other key.
Here's a jQuery solution based on Maciej's answer 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
https://jsfiddle.net/Hastig/us00zdo6/
If you're using esma6, you could do the following using sets.
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
As my gist expired ( no one was using it :( ) I decided to update the answer with more 2017 solution. Check below.
You can use my plugin for jquery to detect shortcuts.
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!)
You have small explanation how to use it in readme file. Hope this helps. Feedback more than appreciated.
Edit 2017:
It's 2017 and we don't need jQuery plugins to solve stuff like that. In short you will need something like this:
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.
There are some quirks in new macs connected to boolean keys like for example caps lock.
Read more: https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent#Key_names_and_Char_values
According to @David Tang's solution, here is a quick and dirty customization for capturing Shift+Ctrl+A combination:
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];
});
});
In a small game this could be :
$(document).keydown(function(event){
keys[event.which] = true;
//up
if( keys[38] ){
posY -= 1;
}
// right
if ( keys[39] ){
posX += 1;
}
// down
if( keys[40] ){
posY += 1;
}
// left
if( keys[37] ){
posX -= 1;
}
});
$(document).keyup(function(event){
delete keys[event.which];
});
本文标签: javascriptCan jQuery keypress() detect more than one key at the same timeStack Overflow
版权声明:本文标题:javascript - Can jQuery .keypress() detect more than one key at the same time? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736966383a1957915.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论