Detect multiple keys on single keypress event in jQuery
Solution 1
If you want to detect that the d, e, and v keys 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.
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.
Solution 2
Similar to Vega's...but simpler
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;
});
Solution 3
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)
The code for this would be something like this:
if(e.shiftKey && e.altKey && e.keyCode == 68)
{
alert('l33t!');
}
Solution 4
I have answer from T.J. Crowder in plain javascript for someone who would want to avoid Jquery.
//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;
}
});
Solution 5
A bit more modern solution, takes advantage of arrow functions and 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>
Related videos on Youtube
remarsh
Updated on July 09, 2022Comments
-
remarsh almost 2 years
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.
Call me crazy but I am writing a Chrome extension and want to push D+E+V keys together to force it into a hidden developer mode.
-
yent about 12 yearsThe keyCode can represent only one key. Try to use a combination of keydown + keyup + flags to detect this.
-
Diodeus - James MacFarlane about 12 yearspossible duplicate of Can jQuery .keypress() detect more than one key at the same time?
-
Michał Perłakowski over 8 yearsConsider changing the accepted answer to this. It presents more modern and general approach.
-
-
Selvakumar Arumugam about 12 yearsmm as you have mentioned, i think the order is important for keyboard shortcuts..
ctrl+v
is not same asv+ctrl
-
T.J. Crowder about 12 years@Vega: Modifier keys are a different kettle of fish.
-
Parth Thakkar about 12 yearsthat isn't the answer to the question, is it?
-
lu1s about 12 yearsThis is really good and will work well. If you need to match a sequence of the keys, then you may check the order by pushing to an array: Instead of
down[e.keyCode]=true
, saydown.push(e.keyCode)
and validate instead of this:if(down[68]&&down[69]&&down[86])
, as this:if(down[0]===68&&down[1]===69&&down[2]===86)
. -
gplumb about 12 years@ParthThakkar - From the question, you can derive the requirement: "to force it into a hidden developer mode". Being pragmatic, I suggested a simple alternative to acheive the same end result
-
Parth Thakkar about 12 yearsall right...that may be the way to go...i just thought that wasn't the answer to the required question, so i just asked that...no offence!)
-
FishBasketGordo about 12 yearsI tested this in Chrome, and it wasn't working with the original key codes. I've ran across this before, but I forget why they're different.
-
Blake Plumb over 11 yearsI created a fiddle to complement lu1s comment.
-
poshest over 8 yearsThis won't work if the user continues to hold the Shift key down and presses S a second time. Forcing
saveArray[0] = false
in the S's keydown event (which makes an assumption that the Shift key was released) is a pretty horrible hack. On the other hand, it may just be the reason this worked for you. -
Michał Perłakowski over 8 yearsYou can't assign a value to a variable which has not been yet defined.
-
Michał Perłakowski over 8 yearsPlease don't use
new Array()
. -
Cindy Meister over 8 yearsBased on this discussion in Comments @GPlumb, it would probably be a good idea for you to include the remarks about this being an althernative to the considered approach and why...
-
kapsiR over 8 yearsA variable without being defined at first would be a new variable on the global stack. This should just be an example how this would be possible. If you want, I can provide a JSFiddle, but the question is already marked as resolved...
-
Michał Perłakowski over 8 yearsThis is a bug, not a feature, and also global variables are bad.
-
kapsiR over 8 yearsI know that - it should just be a demostration of the events, not of js itself ;)
-
Michał Perłakowski over 8 yearsWhich still doesn't excuse you from using bad coding practices.
-
kapsiR over 8 yearsI will do better practise next time I post anything
-
T.J. Crowder about 8 years@DreamWave: No, the
keyup
handler clears the flags. -
Sebastian Manuelli almost 3 yearsWorking like a charm, also thank you @lu1s for the keys order ! :)