Насколько часто нам требуется добавлять обработчик какого-то события на страницу? Да практически постоянно. Тем радостнее узнать, что команда Angular позаботилась об этом как следует и создала простой и изящный способ — функцию декоратор @HostListener.
Пользоваться просто и легко, если вы хотя бы раз видели функции-декораторы в Angular. Если не видели, тоже ничего сложного:
@HostListener('eventName', [args])
Первый строковый аргумент — название события DOM, которое мы собираемся слушать и как-то реагировать на его появление. Давно знакомые и родные: click, focus, blur, keypress и т.д.
Второе — необязательный массив аргументов, которые можно передать функции-обработчику, при возникновении события.
Осталось указать функцию-обработчик, которая будет запускаться каждый раз, когда возникает нужное нам событие.
Например, мы хотим обрабатывать событие click у компонента, выводя алерт с сообщением. Пример учебный и выполнен профессионалами, пожалуйста не повторяйте его на живых людях!
@HostListener('click')
onClick(): void {
alert('хуяк!');
}
Как видите, максимально просто и быстро. Стоит упомянуть, что текущее событие будет срабатывать только по клику внутри компонента. И если компонент у вас небольшой по размеру, клик за его пределами обработан не будет.
Что если, внутри компонента нам нужно повесить обработчик события, который будет срабатывать глобально, а не только в текущем компоненте? Тоже достаточно просто. Перед названием события, добавляете: «window:» или «document:» и вуаля! Событие слушается глобально по всей странице:
@HostListener('document:click')
onClick(): void {
alert('хуяк!');
}
Давайте представим другую ситуацию, у нас есть компонент бокового меню, которое должно закрываться по клику снаружи компонента. Для этого как раз и понадобится параметр $event.target, в качестве второго аргумента.
@HostListener("document:click", ["$event.target"])
onClick(element: Element): void {
if (!element.closest(".user-menu")) this.isOpen = false;
}
- Вешаем глобальный обработчик события клик на документ внутри компонента — document:click
- Вводим параметр $event.target — содержащий dom-элемент, по которому случился клик
- Определяем родителя этого элемента — и если это не наш компонент меню — закрываем меню
- Профит!
Если нужно обрабатывать нажатие определенной клавиши — нет ничего проще. Забудьте про проверку keyCode, она в прошлом.
@HostListener('keydown.enter')
onEnterClick(): void {
alert('нажата клавиша Enter!');
}
Да, вам не показалось. Просто точка и название клавиши.
А если нужна обработка комбинации клавиш? Ни слова больше!
@HostListener('document:keydown.control.r', ['$event'])
onControlPClick(event: KeyboardEvent): void {
event.preventDefault();
alert('Не пытайтесь перезагрузить страницу!');
}
Здесь уже обработчик глобальный, поэтому не будет лишним сделать preventDefault() чтобы наш код сработал, вместо перезагрузки страницы. На всякий случай сообщаю, пользователь никогда в жизни не вернется на ваш сайт, увидев подобное.
Хозяйке на заметку: при таком указании клавиш, раскладка клавиатуры будет иметь значение, поэтому на русской раскладке, например, событие не сработает.
Что еще нужно знать? Обработчик, навешенный через @HostListener будет жить, пока жив его компонент. Способа его корректно удалить не задекларировано, поэтому вы сильно-то не увлекайтесь. И в случае чего, используете контролируемый способ — старый добрый addEventListener.
Спасибо за внимание — лайк, шер, репост.