Icarus
Icarus

Reputation: 511

adding keyup and keydown eventlisteners to div

I have a threejs scene that implements some hotkeys using 'keyup' and 'keydown' eventlisteners like so

//works
window.addEventListener('keydown', (e) => this.onKeyDown(e), false);
window.addEventListener('keyup', (e) => this.onKeyUp(e), false);
window.addEventListener('pointerup', (e) => this.onPointerUp(e), false);
window.addEventListener('pointermove', (e) => this.onPointerMove(e), false);
window.addEventListener('pointerdown', (e) => this.onPointerDown(e), false);

the above code works fine. The problem arises when I move the scene into a div and change the code to the following

//working
this.container.addEventListener('pointerup', (e) => this.onPointerUp(e), false);
this.container.addEventListener('pointermove', (e) => this.onPointerMove(e), false);
this.container.addEventListener('pointerdown', (e) => this.onPointerDown(e), false);
//not working
this.container.addEventListener('keydown', (e) => this.onKeyDown(e), false);
this.container.addEventListener('keyup', (e) => this.onKeyUp(e), false);

for some reasons the keydown and keyup event listeners stop working but the pointer eventlisteners all work fine.

the container looks sth like this

this.container = document.getElementById('canvasWrapper');

Any help would be appreciated

Edit: like Behrouz mentioned in the comment, setting tabindex for the 'canvasWrapper' div fixes the issue i.e.

<div id = "canvasWrapper" tabindex="0">

Upvotes: 1

Views: 393

Answers (1)

Dan Mullin
Dan Mullin

Reputation: 4415

In most languages, this points to a given instance of an object. Simple.

On the other hand, the JavaScript this pointer is a subject which requires a lot of reading and trial and error to understand.

The problem arises from the way the key functions are called.

The event will be triggered by the window object.

In JavaScript, the calling object, window in this case, becomes the this pointer.

You need to bind the function call to ensure the this pointer points to the intended object.

Here’s an example:

var x = {
    message: 'hello',
    init: function () {
        this.addEventListener('keyUp', sayMessage)
    },
    sayMessage: function () {
       console.log(this.message);
    }
}

x.init();

// called directly prints hello
x.sayMessage()

// called from the event lister
// Error: window.message is undefined

Bind the pointer to your object:

x.sayMessage.bind(x)

Upvotes: 1

Related Questions