The keyPressed function only fires once for each key in Chrome - javascript

I am using the P5 library and I want to register key presses. Everything runs as expected on Chrome,Edge and Firefox when the HTML file is opened locally. If I try to host it on github pages it works on Firefox and Edge, but unfortunately not on Chrome. I have tried writing to the console when the keyPressed function detects a key press, which should happen every time a key is pressed, but it only registers the arrow keys once and then ignores they following key presses. Does anyone have a clue about what might be causing this.
function keyPressed(){
if(keyCode === 37){
MoveLeft();
}
if(keyCode === 38){
MoveUp();
}
if(keyCode === 39){
MoveRight();
}
if(keyCode === 40){
MoveDown();
}
if(gameOver === true){
ResetGame();
}
console.log('keyPressed');
return false;
}

var bg = "#333";
var gameover = false;
function draw() {
background(bg);
}
function keyPressed(){
if(gameover){return false;}
if(keyCode === 32){
bg = "#0000FF";
}
return false;
}
function keyReleased(){
bg = "#333";
}
See https://p5js.org/reference/#/p5/keyCode
Use http://keycode.info/

Related

How to track clicks of one button and then another?

I need to track the click on capslock and then the keyboard shortcut ctrl + alt, that is, first click on capslock and then on the keyboard shortcut here is an example
if (e.code == "CapsLock") {
if (e.ctrlKey && e.keyCode == 18) {
alert();
}
}
but this code does not work
I use a function like this:
document.addEventListener("keydown", function (e) {
var caps = e.getModifierState && e.getModifierState('CapsLock'); // true if pressed, false if released
document.onkeyup = function(event) {
if(caps === true){
/** Validate keys are to be processed */
var keycode = event.which;
// works off course only if ctrl key is kept pressed during key stroke = normal behavior in most OS
// Should it work like a ctrl-Lock function you have to work with a state variable
if ((event.ctrlKey === true) && (keycode === 18)) {
alert();
}
else{
/** Let it happen, don't do anything */
return;
}
}
};
});

Multiple keyup events in one JS FILE

I have a JS file for my HTML web page. I want to have 4 things to check. If they hit a number, 1-4 on the keypad, it takes them to a specified url. The script works, but only if I have one.
When I put all 4 events in the js file, only the last one/most recent one works. Is there some kind of syntax that I'm doing wrong that's stopping all of 4 them from working?
To further explain, using this code, only this part of the script runs:
//If they hit keypad number 4
document.body.onkeyup = function(e){
if(e.keyCode == 52){
window.location.href = "foo";
JS:
//If they hit keypad number 1
document.body.onkeyup = function(e){
if(e.keyCode == 49){
window.location.href = "http://localhost:1337/trail";
}
}
//If they hit keypad number 2
document.body.onkeyup = function(e){
if(e.keyCode == 50){
window.location.href = "foo";
}
}
//If they hit keypad number 3
document.body.onkeyup = function(e){
if(e.keyCode == 51){
window.location.href = "http://localhost:1337/topten";
}
}
//If they hit keypad number 4
document.body.onkeyup = function(e){
if(e.keyCode == 52){
window.location.href = "foo";
}
}
If you put all your condition into the same function it will work great. Otherwise you will overwrite your function every times. That is why you got the issue where the only event working was the last one. Last thing, try to use if and then else if. Otherwise you will verify every conditions every single times for no reason.
//If they hit keypad number 1
document.body.onkeyup = function(e){
if(e.keyCode == 49){
window.location.href = "http://localhost:1337/trail";
}
else if(e.keyCode == 50){
window.location.href = "foo";
}
else if(e.keyCode == 51){
window.location.href = "http://localhost:1337/topten";
}
else if(e.keyCode == 52){
window.location.href = "foo";
}
}
This behavior can be explained in this way: What you were trying to do is to assign a function to the onkeyup event. This happens on a same way as when working with variables. Let's say
var key = 1;
is a "reduced" code for
document.body.onkeyup = function(e){
// action for keypad 1
}
then, when assigning another event handling function to your onkeyup, you are doing
key = 2;
Ask yourself a question: does the variable key hold 1? No. That is being overwritten by the above statement. key holds 2 now. The 1 is "lost". That is the reason why the last event handler (for keypad 4) is being executed only. The last assignment has overwritten the previous assignment.
To work around this, you have two options:
group the event actions in one function
use EventTarget.addEventListener
With option 1, you can group your actions in one function like in the interactive example here below:
// input acts as your document.body
const inp = document.getElementById('foo');
inp.onkeyup = function(e) {
if(e.keyCode == 49) {
console.log('pressed keyCode 49'); // press 1
}
else if(e.keyCode == 50) {
console.log('pressed keyCode 50'); // press 2
}
else if(e.keyCode == 51) {
console.log('pressed keyCode 51'); // press 3
}
else if(e.keyCode == 52) {
console.log('pressed keyCode 52'); // press 4
}
};
<input id="foo" type="text" placeholder="type something">
Yet sometimes that is not flexible. Maybe you want to have two different actions to the keyup event. Of course you can group that in one function but what if another js file overwrites the function? Or another snippet further in the js file? That is not productive.
To prevent this, you can use option 2: .addEventListener which is a more robust approach. Here below is an interactive example:
// input acts as your document.body
const inp = document.getElementById('foo');
inp.addEventListener('keyup', function(e) {
if(e.keyCode == 49) {
console.log('first function: keyCode 49'); // press 1
}
});
inp.addEventListener('keyup', function(e) {
if(e.keyCode == 50) {
console.log('second function: keyCode 50'); // press 2
}
});
<input id="foo" type="text" placeholder="type something">
Also, I want to add another suggestion: you were using .keyCode which is deprecated. You can still use but it is not encouraged. It is possible that the browser developers decide to drop this in the future. That leads to a not functioning code.
The problem is that each browser/OS has their own keyCodes which makes it less reliable.
For a clean approach, please consider to use KeyboardEvent.code
Hi and welcome to StackOverflow ;)
You are registering a new onkeyup event listener every time. Try putting the if statements all into one listener like this:
//If they hit keypad number 1
document.body.onkeyup = function(e){
if(e.keyCode == 49){
window.location.href = "http://localhost:1337/trail";
}
if(e.keyCode == 50){
window.location.href = "foo";
}
if(e.keyCode == 51){
window.location.href = "http://localhost:1337/topten";
}
if(e.keyCode == 52){
window.location.href = "foo";
}
}
I hope this helps.
Most people's answer will work however to simply avoid code duplication and a tirade of 'IF' statements, I would just use a switch statement as so :
document.body.onkeyup = function(e){
switch(e.keyCode) {
case 49:
window.location.href = "http://localhost:1337/trail";
break;
case 50:
window.location.href = "foo";
break;
case 51:
window.location.href = "http://localhost:1337/topten";
break;
case 52:
window.location.href = "foo";
break;
}
}
You are overriding the event handler, you need to have one function there. try this option:
//If they hit keypad number 1
document.body.onkeyup = function(e){
if(e.keyCode == 49){
window.location.href = "http://localhost:1337/trail";
} else if(e.keyCode == 50){
window.location.href = "foo";
} else if(e.keyCode == 51){
window.location.href = "http://localhost:1337/topten";
} else if(e.keyCode == 52){
window.location.href = "foo";
}
}
Or you can use a switch instead.
Yes, there is an alternate syntax that allows for multiple event handlers to be added to the same object with out overriding one another.
addEventListener('keyup', functionHere );
/*
// This will work without overriding other functions...
//If they hit keypad number 1
document.body.addEventListener("keyup", function(e){
if(e.keyCode == 49){
window.location.href = "http://localhost:1337/trail";
}
});
//If they hit keypad number 2
document.body.addEventListener("keyup", function(e){
if(e.keyCode == 50){
window.location.href = "foo";
}
});
//If they hit keypad number 3
document.body.addEventListener("keyup", function(e){
if(e.keyCode == 51){
window.location.href = "http://localhost:1337/topten";
}
});
//If they hit keypad number 4
document.body.addEventListener("keyup", function(e){
if(e.keyCode == 52){
window.location.href = "foo";
}
});
*/
// It may be best to combine them all even when using this method...
document.body.addEventListener("keyup", function(e) {
//If they hit keypad number 1
if (e.keyCode == 49) {
window.location.href = "http://localhost:1337/trail";
}
//If they hit keypad number 2
if (e.keyCode == 50) {
window.location.href = "foo";
}
//If they hit keypad number 3
if (e.keyCode == 51) {
window.location.href = "http://localhost:1337/topten";
}
//If they hit keypad number 4
if (e.keyCode == 52) {
window.location.href = "foo";
}
});
Maybe add all your ifs inside one event listener:
document.body.addEventLister("keydown", function(e) {
if (e.key == "Digit1") {
window.location.href = "http://localhost:1337/trail";
}
if (e.key == "Digit2") {
window.location.href = "foo";
}
if (e.key == "Digit3") {
window.location.href = "http://localhost:1337/topten";
}
if (e.keyCode == "Digit4") {
window.location.href = "foo";
}
}

Handling WASD and Arrows simultaneously in JavaScript game

Let's assume the simple pong game for two players with one keyboard.
The movement handler appears to be easy:
document.addEventListener('keydown', function (event) {
if (event.keyCode === 87) { //w
movePaddle(leftPaddle, 0);
} else if (event.keyCode === 83) { //s
movePaddle(leftPaddle, 1);
} else if (event.keyCode === 38) { //arrow_up
movePaddle(rightPaddle, 0);
} else if (event.keyCode === 40) { //arrow_down
movePaddle(rightPaddle, 1);
}
});
The second argument in movePaddle function just means the direction (up or down).
The problem: if W and Up Arrow are pressed together, then only one paddle moves. It depends on which key were pressed last.
How to handle keydown events correctly?
I need two paddles moving together according pressed keys. If W and Up Arrow, then both go up. If W and Down Arrow, then left goes up and right goes down. Of course, only one paddle should move if only one key are pressed.
https://gist.github.com/RepComm/52690eadaa9f4a3e7a7819b3267feca4
Use it like this: (In a loop of any kind, this one just uses anim frame)
Input.init();
var test = function () {
window.requestAnimationFrame(test);
if (Input.isKeyDown("w")) {
console.log("Forward March!");
}
}
window.requestAnimationFrame(test);
Try separating the keys by saying
document.addEventListener('keydown', function (event) {
if (event.keyCode === 87) { //w
movePaddle(leftPaddle, 0);
} else if (event.keyCode === 83) { //s
movePaddle(leftPaddle, 1);
}
// Separate them here
if (event.keyCode === 38) { //arrow_up
movePaddle(rightPaddle, 0);
} else if (event.keyCode === 40) { //arrow_down
movePaddle(rightPaddle, 1);
}
});
This will work because you're saying else if for every single one, that means that only one of them can be true at the same time.
What I'm saying is that when using else if, the else if is paired to the if, and much like just else, only one of the blocks can be true at the same time

How to continue playing sound when holding key?

I have a sound in JavaScript that plays when you press the up arrow key.
I would like to have the sound play when you hold the up arrow key, then pause when you release the key.
This is my code now:
var clickSound = new Audio("img/hartslag.mp3");
document.body.onkeyup = function (e){
if(e.keyCode == 38){
clickSound.play();
}
}
You would need to listen to 2 different events. Play on key down and pause on key up.
var clickSound = new Audio("img/hartslag.mp3");
var playing = false;
document.body.onkeydown = function (e){
if(e.keyCode == 38 && !playing){
clickSound.play();
playing=true;
} }
document.body.onkeyup = function (e){
if(e.keyCode == 38){
clickSound.pause();
playing=false;
} }
Code is not tested!

How to stop of running the keycodes 37 and 39 when there is a textarea selected

Simply I have a js script that change the page with left and right arrows, but how to stop that if a specific textarea is selected ?
This is my js to change the page
$(document).keydown(function(event) {
if(event.keyCode === 37) {
window.location = "http://site.com/pics/5";
}
else if(event.keyCode === 39) {
window.location = "http://site.com/pics/7";
}
});
$('textarea').on('keypress', function(evt) {
if ((evt.keyCode === 37) || (evt.keyCode === 39)) {
console.log('stop propagation');
evt.stopPropagation();
}
});
See example fiddle: http://jsfiddle.net/GUDqV/1
Update: after OP clarification this works even on jQuery 1.2.6 on Chrome: http://jsfiddle.net/GUDqV/2/
$('textarea').bind('keyup', function(evt) {
if ((evt.keyCode === 37) || (evt.keyCode === 39)) {
console.log('stop propagation');
evt.stopPropagation();
}
});​
see screenshot of this code on Chrome and jQ1.2.6
Probably the simplest approach is to factor event.target into your code, checking to see if it is the textarea:
$(document).keydown(function(event) {
if (event.target.id == "myTextArea") {
return true;
}
else if(event.keyCode === 37) {
window.location = "http://site.com/pics/5";
}
else if(event.keyCode === 39) {
window.location = "http://site.com/pics/7";
}
});
Any key events that originate from a textarea element with an id of myTextArea will then be ignored.
You can check if the textarea is in focus by doing something like:
if (document.activeElement == myTextArea) {
// Don't change the page
}
$("#mytextarea").is(":focus") This will let you know if the element is focused.
Also $(document.activeElement) will get the currently focused element.
You can check to see if your text area is focused, and disable the script that navigates when using left and right arrow keys.
A little bit of code showing what you've tried might bring in more specific responses.
Hope this helps.

Categories

Resources