javascript - Angular window resize event

ID : 10197

viewed : 14

Tags : javascriptangularjavascript

Top 5 Answer for javascript - Angular window resize event

vote vote

90

<div (window:resize)="onResize($event)" 
onResize(event) {   event.target.innerWidth; } 

or using the HostListener decorator:

@HostListener('window:resize', ['$event']) onResize(event) {   event.target.innerWidth; } 

Supported global targets are window, document, and body.

Until https://github.com/angular/angular/issues/13248 is implemented in Angular it is better for performance to subscribe to DOM events imperatively and use RXJS to reduce the amount of events as shown in some of the other answers.

vote vote

81

I know this was asked a long time ago, but there is a better way to do this now! I'm not sure if anyone will see this answer though. Obviously your imports:

import { fromEvent, Observable, Subscription } from "rxjs"; 

Then in your component:

resizeObservable$: Observable<Event> resizeSubscription$: Subscription  ngOnInit() {     this.resizeObservable$ = fromEvent(window, 'resize')     this.resizeSubscription$ = this.resizeObservable$.subscribe( evt => {       console.log('event: ', evt)     }) } 

Then be sure to unsubscribe on destroy!

ngOnDestroy() {     this.resizeSubscription$.unsubscribe() } 
vote vote

78

@G√ľnter's answer is correct. I just wanted to propose yet another method.

You could also add the host-binding inside the @Component()-decorator. You can put the event and desired function call in the host-metadata-property like so:

@Component({   selector: 'app-root',   templateUrl: './app.component.html',   styleUrls: ['./app.component.css'],   host: {     '(window:resize)': 'onResize($event)'   } }) export class AppComponent{    onResize(event){      event.target.innerWidth; // window width    } } 
vote vote

62

The correct way to do this is to utilize the EventManager class to bind the event. This allows your code to work in alternative platforms, for example server side rendering with Angular Universal.

import { EventManager } from '@angular/platform-browser'; import { Observable } from 'rxjs/Observable'; import { Subject } from 'rxjs/Subject'; import { Injectable } from '@angular/core';  @Injectable() export class ResizeService {    get onResize$(): Observable<Window> {     return this.resizeSubject.asObservable();   }    private resizeSubject: Subject<Window>;    constructor(private eventManager: EventManager) {     this.resizeSubject = new Subject();     this.eventManager.addGlobalEventListener('window', 'resize', this.onResize.bind(this));   }    private onResize(event: UIEvent) {     this.resizeSubject.next(<Window>event.target);   } } 

Usage in a component is as simple as adding this service as a provider to your app.module and then importing it in the constructor of a component.

import { Component, OnInit } from '@angular/core';  @Component({   selector: 'my-component',   template: ``,   styles: [``] }) export class MyComponent implements OnInit {    private resizeSubscription: Subscription;    constructor(private resizeService: ResizeService) { }    ngOnInit() {     this.resizeSubscription = this.resizeService.onResize$       .subscribe(size => console.log(size));   }    ngOnDestroy() {     if (this.resizeSubscription) {       this.resizeSubscription.unsubscribe();     }   } } 
vote vote

56

Here is a better way to do it. Based on Birowsky's answer.

Step 1: Create an angular service with RxJS Observables.

import { Injectable } from '@angular/core'; import { Observable, BehaviorSubject } from 'rxjs';  @Injectable() export class WindowService {     height$: Observable<number>;     //create more Observables as and when needed for various properties     hello: string = "Hello";     constructor() {         let windowSize$ = new BehaviorSubject(getWindowSize());          this.height$ = (windowSize$.pluck('height') as Observable<number>).distinctUntilChanged();          Observable.fromEvent(window, 'resize')             .map(getWindowSize)             .subscribe(windowSize$);     }  }  function getWindowSize() {     return {         height: window.innerHeight         //you can sense other parameters here     }; }; 

Step 2: Inject the above service and subscribe to any of the Observables created within the service wherever you would like to receive the window resize event.

import { Component } from '@angular/core'; //import service import { WindowService } from '../Services/window.service';  @Component({     selector: 'pm-app',     templateUrl: './componentTemplates/app.component.html',     providers: [WindowService] }) export class AppComponent {       constructor(private windowService: WindowService) {          //subscribe to the window resize event         windowService.height$.subscribe((value:any) => {             //Do whatever you want with the value.             //You can also subscribe to other observables of the service         });     }  } 

A sound understanding of Reactive Programming will always help in overcoming difficult problems. Hope this helps someone.

Top 3 video Explaining javascript - Angular window resize event

Related QUESTION?