Именованный обработчик события в методе класса
Приветствую всех!
Есть класс, управляющий движением элемента по экрану, в нем метод start():
start() {
document.addEventListener('keydown', (event) => {
... <некий код> ...
});
document.addEventListener('keyup', (event) => {
... <некий код> ...
});
}
Проблема в следующем: функциям-обработчикам нужно дать имена, чтобы в дальнейшем можно было сослаться на них для удаления EventListener. Пробовал делать их методами класса:
onKeyDown(event) {
}
onKeyUp(event) {
}
или даже глобальными:
function onKeyDown(event) {
}
function onKeyUp(event) {
}
- не работает. Только если код функции встраивается inline, тогда все ок. Как победить проблему? |
Хранить всё в классе, имеющем специальный метод handleEvent и передавать в listener просто this.
|
Глубокая мысль. Попробую.
|
Вот она проблемка, определился с ней наконец-то:
class MyClass {
constructor(x) {
this.x = x;
}
onKeyDown(event) { // Если эту функцию привязать к EventListener,
console.log(this); // то this из нее будет смотреть на document, x не виден
}
start() {
document.addEventListener('keydown', this.onKeyDown);
document.addEventListener('keydown', (event) => {
console.log(this); // а отсюда this будет смотреть на объект класса MyClass и прекрасно увидит this.x
});
}
}
window.onload = function() {
let c = new MyClass(5);
c.start();
};
Как объяснить, почему так происходит? Как сделать так, чтобы из поименованной функции виделся x? |
Потому что для стрелочной функции this - это конкретно this контекста объявления оной, а для нормальной функции this зависит от условий вызова.
Можно конечно использовать стрелочные функции, но именно для вашего случая и придумали передачу объекта:
class MyClass {
constructor(x) {
this.x = x;
}
onKeyDown(event) {
console.log(this);
}
onKeyUp(event) {
console.log(this);
}
handleEvent(event) {
switch(event.type) {
case 'keydown':
return this.onKeyDown(event);
case 'keyup':
return this.onKeyUp(event);
// ...
}
}
start() {
document.addEventListener('keydown', this);
document.addEventListener('keyup', this);
}
}
window.addEventListener('load', function() {
let c = new MyClass(5);
c.start();
});
|
Отлично, это как раз самое то, что меня устроит. Спасибо!
|
| Часовой пояс GMT +3, время: 07:26. |