alexp2603
alexp2603

Reputation: 365

eventListener can't read keyCode

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

Answers (2)

kennytm
kennytm

Reputation: 523344

  1. Yes drop the (), you are using the function itself to the event listener, not the result of the function call.

  2. 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

Andrew Messier
Andrew Messier

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

Related Questions