Multiple keyup events in one JS FILE
Asked Answered
P

7

12

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";
    }
}
Photo answered 27/9, 2018 at 6:26 Comment(3)
just use a condition inside your event call instead of writing in again and againKalil
It might be overkill, but for keyboard input and better readability you might want to have a look at mousetrapEstray
Just create a map of keycode-url pairs {49: 'http://...', 50: 'http://...'}.Sinistrodextral
W
13

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";
    }
}
Whatever answered 27/9, 2018 at 6:34 Comment(2)
Or use a switch statement.Izzy
Or a mapping object: var locations = {'49': 'trail', '50': 'foo', '51': 'topten', '52': 'foo'}; if (locations[e.keyCode]) window.location.href = locations[e.keyCode];Rossierossing
L
7

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:

  1. group the event actions in one function
  2. 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

Leavenworth answered 27/9, 2018 at 6:59 Comment(0)
G
3

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.

Glialentn answered 27/9, 2018 at 6:31 Comment(0)
F
3

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;
    }
}
Fleeman answered 27/9, 2018 at 12:37 Comment(0)
G
2

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.

Gery answered 27/9, 2018 at 6:32 Comment(0)
H
1

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";
  }
});
Helminthology answered 27/9, 2018 at 6:37 Comment(0)
S
1

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";
    }
}
Silicium answered 27/9, 2018 at 6:42 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.