Обложка: Как создать объект для обработки событий в JavaScript?

Как создать объект для обработки событий в JavaScript?

Чтобы создавать интерактивные веб-приложения нужно использовать события JavaScript. Как они работают?

Вы указываете нужный тип события, добавляете коллбэк, и теперь можете обрабатывать клики, нажатия клавиш, прокрутку и другие события.

Например, чтобы обработать нажатие кнопки, можно использовать следующий код:

document.querySelector('button')
  .addEventListener('click', () => {
    console.log('кнопка нажата');
  });

Этот код обращается к DOM, находит указанный элемент, и добавляет обработчик события click используя addEventListener.

В соответствии с документацией DOM, target.addEventListener может иметь следующие параметры:

target.addEventListener(type, listener [, options]);
target.addEventListener(type, listener [, useCapture]);
target.addEventListener(type, listener [, useCapture, wantsUntrusted  ]); // только в браузерах Gecko/Mozilla

addEventListener принимает: тип события, коллбэк и параметр options/useCapture. Подробнее о возможных значениях параметров в документации событий JavaScript.

Параметр listener может быть не только функцией но и объектом.

Обработка событий JavaScript с помощью addEventListener и EventListener

MDN описывает listener так:

listener может быть объектом реализующим интерфейс EventListener или JavaScript функцией

В ранней версии спецификации событий DOM (до HTML5), описан интерфейс EventListener. Реализующие его объекты должны содержать метод handeEvent. Они могут использоваться с addEventListener.

// класс, реализующий
// интерфейс `EventListener`
class EventHandler {
  constructor() {
    this.eventCount = 0;
  }

  handleEvent() {
    this.eventCount++;
    console.log(`Событие обработано ${this.eventCount} раз`);
  }
}

document.querySelector('button')
  .addEventListener('click', new EventHandler());

Это код класса EventHandler. Инициализированные объекты обработчиков событий могут быть переданы в addEventListener. Обработчик считает количество событий нужного типа. Попробуйте этот код на CodePen. Вся информация хранится в самом объекте и код работает без внешних переменных. Мне нравится этот паттерн, он пригодится для работы с последовательными событиями.

MDN говорит, что интерфейс EventListener поддерживается большинством браузеров и вы можете безопасно передавать реализующие его объекты в addEventListener. Когда их нужно передавать? Объясню на примере:

class MyComponent {
  constructor (el) {
    this.el = el
    this.el.addEventListener('click', this)
  }
  handleEvent (event) {
    console.log('my component элемент нажат')
  }
  destroy () {
    this.el.removeEventListener('click', this)
  }
}

const component = new MyComponent(
  document.querySelector('button')
);

Конструктор класса MyComponent принимает элемент DOM в качестве аргумента и сам добавляет\удаляет его обработчики событий JavaScript. Класс реализует интерфейс EventListener, а следовательно вы можете передавать this в addEventListener.

***

Для того чтобы ваш интерфейс был удобным и интерактивным, важно не только использовать события JavaScript, но и учитывать размер области нажатия. Подробнее о том, как помочь юзеру не промахнуться, читайте в статье: «Хотел кликнуть, но не смог: как правильно настроить размер области клика».

Источник addEventListener accepts functions and (!) objects