Hey developers! 👋
Welcome back to our series on Angular decorators. In this post, we're diving into one of the lesser-discussed but incredibly powerful decorators in Angular: @HostListener
. We’ll explore how to use it, how it gets compiled under the hood, and a few interesting use cases you may not have tried before.
🎯 What is @HostListener
?
The @HostListener
decorator allows you to listen to DOM events on the host element of a directive or component and run custom logic in response. It’s a clean way to bind events without touching the template.
🧠 Syntax
@HostListener(eventName: string, [args: string[]])
🧪 Use Case 1: Listening to DOM Events on Host Element
Let’s start with a basic example where we listen to native DOM events like mouseover
and mouseleave
to dynamically apply styles.
We’ll create a directive that zooms in text when hovered.
✅ Step 1: The Directive
import { Directive, ElementRef, HostListener, inject, Renderer2 } from '@angular/core';
@Directive({
selector: 'strong', // Applies to all <strong> elements
})
export class ZoomIn {
private _el = inject(ElementRef);
private renderer = inject(Renderer2);
@HostListener('mouseover', ['$event'])
mouseOver(event: MouseEvent) {
this.renderer.addClass(this._el.nativeElement, 'zoom');
}
@HostListener('mouseleave', ['$event'])
mouseLeave(event: MouseEvent) {
this.renderer.removeClass(this._el.nativeElement, 'zoom');
}
}
✅ Step 2: The Component
import { Component } from '@angular/core';
import { ZoomIn } from '../../directive/zoom-in';
@Component({
selector: 'app-about',
standalone: true,
imports: [ZoomIn],
template: `
<section>
<h2>About Me</h2>
<p>
I’m a <strong>frontend developer</strong> with a strong focus on
<strong>Angular</strong>, currently working with
<strong>Angular 20</strong> and exploring advanced UI effects to enhance
user experience.
</p>
</section>
`,
styleUrls: ['./about.scss'],
})
export class About {}
✅ Step 3: Styles (about.scss
)
.zoom {
transition: transform 1s;
}
.zoom:hover {
font-size: 20px;
color: #81E7AF;
}
🎉 Result: When a user hovers over any
<strong>
tag, the zoom effect kicks in!
🌐 Use Case 2: Listening to Global Events (Window, Document, etc.)
@HostListener
isn’t limited to the host element. Angular also allows you to bind global events like window:resize
.
Example:
@HostListener('window:resize', ['$event'])
onResize(event: Event) {
console.log('Window resized', event);
}
You can also listen to other global targets like document
or body
:
@HostListener('document:click', ['$event'])
onDocumentClick(event: MouseEvent) {
console.log('Document clicked', event);
}
🎹 Use Case 3: Listening to Specific Key Combinations
You can use @HostListener
to capture specific key events—just like in plain JavaScript!
Example: Show an alert when Shift + I
is pressed
@HostListener('window:keydown.shift.i', ['$event'])
onShortcut(event: KeyboardEvent) {
alert('Info shortcut triggered!');
}
This is super useful for building shortcuts or accessibility features directly into your components.
🧩 How @HostListener
Works Under the Hood
Under the hood, @HostListener
is just syntactic sugar provided by Angular. It’s implemented via Angular’s makePropDecorator
function:
export const HostListener: HostListenerDecorator = makePropDecorator(
'HostListener',
(eventName?: string, args?: string[]) => ({ eventName, args }),
);
When compiled by Angular (Ivy), your decorator gets transformed into low-level host bindings like:
hostBindings: function About_HostBindings(rf, ctx) {
if (rf & 1) {
ɵɵlistener("resize", function About_resize($event) {
return ctx.onResize($event);
}, ɵɵresolveWindow);
ɵɵlistener("keydown.shift.i", function About_shortcut($event) {
return ctx.onShortcut($event);
}, ɵɵresolveWindow);
}
}
That’s how Angular internally registers the event listeners during render.
🧠 Final Thoughts
The @HostListener
decorator is a clean, Angular-idiomatic way to handle DOM and global events. It:
- Keeps event handling logic close to the component or directive class
- Works seamlessly with Angular's DI and change detection
- Helps encapsulate behavior without touching templates
Whether you're creating reusable directives or handling responsive layouts, @HostListener
can significantly streamline your codebase.
💬 Got questions or use cases you want to share? Drop a comment below! Let's discuss more Angular magic. ✨
✍️ Author: Vetriselvan
👨💻 Frontend Developer | Code Lover | Exploring Angular’s future
Top comments (0)