Handle Keyboard in JavaScript
1. List of Action functions
Create an Object literal list with your desired functions. Say you have a character you want to move, here are some example Actions:
const Action = {
powerOn() { console.log("Accelerating..."); },
powerOff() { console.log("Decelerating..."); },
brakeOn() { console.log("Break activated"); },
brakeOff() { console.log("Break released"); },
exit() { console.log("Nice drive!"); },
// clutch, colors, lights, fire... Add more, go wild!
};
PS: In a real-case scenario every single function would contain the actual logic to handle the character, being it a one-time "move-by-N-px", or act as a proxy to populate a queue which is than consumed by a frame-rate engine like Window.requestAnimationFrame. You can also create functions to change colors, etc. You got the general idea.
2. Associate Keys to Actions by Event.type
Associate KeyboardEvent.key to the desired Action for a desired Event.type (←must be lowercase):
const keyAction = {
w: { keydown: Action.powerOn, keyup: Action.powerOff },
s: { keydown: Action.brakeOn, keyup: Action.brakeOff },
Escape: { keydown: Action.exit }
};
Notice that the key-names "w"
"s"
"Escape"
are represented as the returned value of the preferred KeyboardEvent.key
, instead of the numeric KeyboardEvent.keyCode
. We're humans, not robots.
3. KeyboardEvent handler
Finally, let's listen to the "keyup"
"keydown"
Events and trigger a callback function keyHandler
, that will eventually trigger our specific Action function, say i.e: keyAction["w"]["keydown"]()
which is actually our spaceship's powerOn
Action function!
const keyHandler = (ev) => {
if (ev.repeat) return; // Key-held, prevent repeated Actions (Does not work in IE11-)
if (!(ev.key in keyAction) || !(ev.type in keyAction[ev.key])) return; // No such Action
keyAction[ev.key][ev.type](); // Trigger an Action
};
['keydown', 'keyup'].forEach((evType) => {
document.body.addEventListener(evType, keyHandler);
});
Result:
const Action = {
powerOn() { console.log("Accelerating..."); },
powerOff() { console.log("Decelerating..."); },
brakeOn() { console.log("Break activated"); },
brakeOff() { console.log("Break released"); },
exit() { console.log("Nice drive!"); },
};
const keyAction = {
w: { keydown: Action.powerOn, keyup: Action.powerOff },
s: { keydown: Action.brakeOn, keyup: Action.brakeOff },
Escape: { keydown: Action.exit }
};
const keyHandler = (ev) => {
if (ev.repeat) return;
if (!(ev.key in keyAction) || !(ev.type in keyAction[ev.key])) return;
keyAction[ev.key][ev.type]();
};
['keydown', 'keyup'].forEach((evType) => {
document.body.addEventListener(evType, keyHandler);
});
Click here to focus this window.<br>
Then, use [<kbd>W</kbd>], [<kbd>S</kbd>] or [<kbd>Esc</kbd>] keys on your keyboard.
Example for your specific request:
const changeBG = (color) => document.body.style.background = color;
const Action = {
red() { changeBG("#f00"); },
yellow() { changeBG("yellow"); },
orange() { changeBG("orange"); },
reset() { changeBG(""); },
};
const keyAction = {
r: { keydown: Action.red, keyup: Action.reset },
y: { keydown: Action.yellow, keyup: Action.reset },
o: { keydown: Action.orange }, // No keyup for this one :)
};
const keyHandler = (ev) => {
if (ev.repeat) return;
if (!(ev.key in keyAction) || !(ev.type in keyAction[ev.key])) return;
keyAction[ev.key][ev.type]();
};
['keydown', 'keyup'].forEach((evType) => {
document.body.addEventListener(evType, keyHandler);
});
body { transition: background: 0.3s; }
Click here to focus this window. <br>Keys:<br>
[<kbd>Y</kbd>] for Yellow<br>
[<kbd>R</kbd>] for Red<br>
[<kbd>O</kbd>] to permanently set to Orange
e.which
instead ofe.keyCode
? https://mcmap.net/q/22253/-jquery-event-keypress-which-key-was-pressed – Elga