Get #Amazon #Prime for this #holiday #amazonprime #christmas #2019

#Angular #event listener using Renderer2 and HostListener

What is the list of events that you can attach to your HTML elements? They are basically DOM events. I got the following list of DOM events from MDN.

addEventListener
addEventListener

DOM events on MDN

Check out the following list of events on MDN:
abort
beforeinput
blur
click
compositionstart
compositionupdate
compositionend
dblclick
error
focus
focusin
focusout
input
keydown
keypress
keyup
load
mousedown
mouseenter
mouseleave
mousemove
mouseout
mouseover
mouseup
resize
scroll
select
unload
wheel

How to listen for these events?

1) You can then listen for them like so if you use Angular.

<div role='Listbox' (keyup)='handleKeyUpEvent($event)' (keydown)='handleKeyDownEvent($event)'>
  <span tabIndex='1' (blur)='listBlur()' (click)='listActivated()'
        (click)='toggleDropDownList()'
        [ngClass]='titleClasses'>{{title || 'DropDownList'}}</span>
  <ul role='List' [ngClass]='listClasses'>
    <li
      role='Listitem'
      (click)='selectItem(item)'
      *ngFor='let item of listItems; let i = index'
      [class.selected]='i === activeIndex'
      [selected]='i === activeIndex'>{{i + 1}}: {{item.data}}
    </li>
  </ul>
  <span [ngClass]='clearClasses' (click)='deselectItem()'>Clear</span>
</div>

2) Using Renderer2
You can check out this Angular Renderer2 plunkr fork what I found to see how to use Renderer2 to listen for some events.

import {Component, NgModule, Renderer2, ViewChild} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'

@Component({
  selector: 'my-app',
  template: `
    <button #myButton>Click me</button>
  `,
})
export class App {
  @ViewChild('myButton') myButton;
  documentClick; 
  buttonClick; 

  constructor(private renderer: Renderer2) {}
  
  ngOnInit() {
    documentClick = this.renderer.listen('document', 'click', (evt) => {
      console.log('Clicking the document', evt);
    })
   
    buttonClick = this.renderer.listen(this.myButton.nativeElement, 'click', (evt) => {      
      console.log('Clicking the button', evt);
    });  
  }

  ngOnDestroy() {
    documentClick(); // to unsubscribe
    buttonClick(); // to unsubscribe
  }
}


3) Using HostListener with a directive

Then, HostListener of the Click Directive will listen for click event of its host and call the onClick function.
HostListener can listen for custom events as well.

ClickDirective file
import { Directive, HostListener } from '@angular/core';

@Directive({
  selector: '[onClick]'
})
export class ClickDirective {
  constructor() { }

  @HostListener('click', ['$event'])
  onClick(event: UIEvent): void {
    console.log(event)
    // do something
  }
}

Use the directive in a component

import { Component } from '@angular/core';
import { ClickDirective } from './directives/click.directive';

@Component({
  selector: 'app',
  template: `
    <p onClick>Click here</p>
  `,
  directives: [ClickDirective]
})
export class AppComponent { }

Note

1) I believe there is ElementRef but it is deprecated or will be deprecated so you shouldn't use it.

2) I was looking for a way to listen for events with once, capture or passive option but I haven't found a way yet. I will update once I find it.

Thanks for reading!

Jun