Reputation: 365
So I'm working on a game that will accept user input (up down left right arrow keys). To do so, I will add an event listener that will check when the user presses said keys. I have it set up in the following way:
function gameStart(){
//Generates four random numbers on board
for(gameStart_i = 0; gameStart_i < 4; gameStart_i++){
generateNumber();
}
document.getElementById("start_button").innerHTML = "Reset Game";
document.getElementById("start_button").setAttribute('onclick', 'reset()');
document.getElementById("start_button").id = 'reset_button';
var board = document.getElementById("game_background");
console.log("1");
board.addEventListener("keydown", inputListen(), false);
console.log("1.1");
}
function inputListen(e){
console.log("2");
var code = e.keyCode;
switch(code){
case 37:
alert("left");
break;
case 38:
alert("up");
break;
case 39:
alert("right");
break;
case 40:
alert("down");
break;
}
}
This seems in line with how tutorials show it. However, some tutorials change the addEventListener line with something that would look like this:
board.addEventListener("keydown", inputListen, false); //removes the () after the function
However that doesn't seem to work for me when I look into my console.
When I run my code my console gives me the following error:
1
2
Uncaught TypeError: Cannot read property 'keyCode' of undefined
at inputListen (script.js:86)
at gameStart (script.js:16)
at HTMLButtonElement.onclick (2048Game.html:114)
I think it's because I don't pass any parameters to my function, but none of the online tutorials pass paraements in their addEventListener statement.
Thank you, Alex
Upvotes: 1
Views: 2126
Reputation: 523344
Yes drop the ()
, you are using the function itself to the event listener, not the result of the function call.
The keydown
event is likely not sent to an arbitrary <div>
in the page. Add the event listener to the window itself instead, if you don't want the user to manually click to focus on it.
window.addEventListener('keydown', inputListen);
Upvotes: 1
Reputation: 834
The proper way to do this is indeed to remove the ()
after inputListen
.
Using the ()
immediately calls the function, which then gives you aforementioned Cannot read property 'keycode' of undefined
since no input parameters were given.
You should have also received the error in the console between the two console.log
lines, which proves the error came from the addEventListener
line.
You want to pass the function without calling it using the line you posted:
board.addEventListener("keydown", inputListen, false); //removes the () after the function
Take a look at this JSFiddle:
function gameStart(){
console.log("before");
document.getElementById("game_background").addEventListener("keydown", inputListen, false);
console.log("after");
}
This should print out to the console
before
after
And then nothing else until it detects a keydown
.
It also matters what kind of element you bind this to. An element such as <input>
will have no trouble here, but normal non-focusable elements will need the tabindex
attribute in order to be focused and respond to a keydown
:
<div id="game_background" tabindex="-1">
</div>
You'll need to click the element once to focus onto it, then your events should be captured. More info at this answer.
Upvotes: 2