I'm trying to make the background color change when certain keys are held down. For example, when the 'r' key is being held down, the background should be red. When the 'r' key is not being pressed anymore, the background should default to white.
$(document).ready(function () {
$('body').keydown(function(e){
if(e.keyCode == 114){
$(this).css({'background':'red'});
}
if(e.keyCode == 121){
$(this).css({'background':'yellow'});
}
});
$('body').keypress(function(e){
if(e.keyCode == 114){
$(this).css({'background':'red'});
}
if(e.keyCode == 121){
$(this).css({'background':'yellow'});
}
});
$('body').keyup(function(e){
if(e.keyCode == 114){
$(this).css({'background':'white'});
}
if(e.keyCode == 121){
$(this).css({'background':'white'});
}
});
});
The problem I'm having is that keyup is not working specifically for each individual key.
$('body').keyup(function(e){
$(this).css({'background':'white'});
});
I know if I remove the if conditionals from keyup altogether then it will behave how I said I wanted it to — but I want to be able to do different things later on using keyup with specific keys. For example, when just the 'b' key is released, maybe it will say something on the screen like "You just released the b key!" How can I keep track of keydown and keyup events for specific keys and make different things happen for each? I know this isn't very organized either (I'm pretty new to this stuff) so if there's a completely different and better way of doing this...
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.
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.
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);
});
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 fucus this window.<br>
Than, use [<kbd>W</kbd>], [<kbd>S</kbd>] or [<kbd>Esc</kbd>] keys on your keyboard.
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 fucus 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