Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Именованный обработчик события в методе класса (https://javascript.ru/forum/events/78956-imenovannyjj-obrabotchik-sobytiya-v-metode-klassa.html)

deGeneral 27.11.2019 17:34

Именованный обработчик события в методе класса
 
Приветствую всех!

Есть класс, управляющий движением элемента по экрану, в нем метод start():

start() {

        document.addEventListener('keydown', (event) => {
            ... <некий код> ...
        });

        document.addEventListener('keyup', (event) => {
             ... <некий код> ...
        });
}


Проблема в следующем: функциям-обработчикам нужно дать имена, чтобы в дальнейшем можно было сослаться на них для удаления EventListener. Пробовал делать их методами класса:

onKeyDown(event) {
}

onKeyUp(event) {
}


или даже глобальными:

function onKeyDown(event) {
}

function onKeyUp(event) {
}


- не работает. Только если код функции встраивается inline, тогда все ок.

Как победить проблему?

Aetae 27.11.2019 18:08

Хранить всё в классе, имеющем специальный метод handleEvent и передавать в listener просто this.

deGeneral 27.11.2019 18:53

Глубокая мысль. Попробую.

deGeneral 27.11.2019 22:27

Вот она проблемка, определился с ней наконец-то:

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?

Aetae 27.11.2019 22:55

Потому что для стрелочной функции 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();
});

deGeneral 27.11.2019 23:22

Отлично, это как раз самое то, что меня устроит. Спасибо!


Часовой пояс GMT +3, время: 09:58.