@taiga-ui/event-plugins is a tiny (1KB gzip) library for optimizing change detection cycles for performance sensitive events (such as touchmove, scroll, drag etc.) and declarative preventDefault() and stopPropagation().
-
Add
NG_EVENT_PLUGINS
to your app providers:bootstrapApplication(AppComponent, { providers: [NG_EVENT_PLUGINS], });
-
Use new modifiers for events in templates and in
@HostListener
:-
.stop
to call stopPropagation() on event -
.prevent
to call preventDefault() on event -
.self
to skip bubbled events -
.silent
to call event handler outside Angular'sNgZone
-
.capture
to listen to events in capture phase -
.passive
to add passive event listener -
.once
to remove event listener after first callback -
resize
to watch for elements changing dimensions withResizeObserver
For example:
<div (mousedown.prevent)="onMouseDown()">Clicking on this DIV will not move focus</div>
<div (click.stop)="onClick()">Clicks on this DIV will not bubble up</div>
<div (mousemove.silent)="onMouseMove()">Callbacks to mousemove will not trigger change detection</div>
<div (click.capture.stop)="onClick()"> <div (click)="never()">Clicks will be stopped before reaching this DIV</div> </div>
-
-
You can also re-enter
NgZone
and trigger change detection, using@shouldCall
decorator that takes a predicate function as argument:
<div (scroll.silent)="onScroll($event.currentTarget)">
Scrolling this DIV will only trigger change detection and onScroll callback if it is scrolled to bottom
</div>
import {shouldCall} from '@taiga-ui/event-plugins';
export function scrollFilter({
scrollTop, scrollHeight, clientHeight
}: HTMLElement): boolean {
return scrollTop === scrollHeight - clientHeight;
}
// ...
@shouldCall(scrollFilter)
onScroll(_element: HTMLElement): void {
this.someService.requestMoreData();
}
- Angular global events only support
body
,window
anddocument
. You can listen to events on any global object with these plugins by replacing:
with>
symbol, for example:
@HostListener('visualViewport>resize', ['$event.target'])
onPinchZoom({ scale }: VisualViewport) {
console.log(scale)
}
- iOS currently doesn't support the
contextmenu
event. Instead, you can use a customlongtap
event. This event captures thecontextmenu
event on non-iOS devices and simulates similar behavior on iOS devices.
<div (longtap)="showContextMenu($event.detail.clientX, $event.detail.clientY)">Div with context menu</div>
All examples above work the same when used with
@HostListener
andCustomEvent
-
Predicate is called with the same arguments as the decorated method and in the context of class instance (has access to
this
) -
Decorated method will be called and change detection triggered if predicate returns
true
. -
.silent
modifier will not work with built-in keyboard pseudo-events, such askeydown.enter
orkeydown.arrowDown
since Angular re-entersNgZone
inside internal handlers.
You can try this interactive demo
You can also read this detailed article explaining how this library works
@taiga-ui/event-plugins is a part of Taiga UI libraries family which is backed and used by a large enterprise. This means you can rely on timely support and continuous development.
🆓 Feel free to use our library in your commercial and private applications
All @taiga-ui/event-plugins packages are covered by Apache 2.0
Read more about this license here