Reputation: 511
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
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