Именованный обработчик события в методе класса
Приветствую всех!
Есть класс, управляющий движением элемента по экрану, в нем метод 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, время: 09:58. |