import { Inject, Injectable, } from '@angular/core'; import { PopStateEvent, } from '@angular/common'; import { NavigationEnd, NavigationStart, Router, } from '@angular/router'; interface RouteTrailInterface { url: string; scroll: { x: number; y: number; }; } @Injectable() export class ScrollToTopOnRouteChangeService { public routeTrail: RouteTrailInterface[] = []; public backRouteTrail: RouteTrailInterface; constructor( private _router: Router, @Inject('window') private _window: Window, ) { } public scrollToTopOnRouteChange() { this._router.events.subscribe((ev) => { if (ev instanceof NavigationStart) { const lastRoute = this.routeTrail[this.routeTrail.length - 2]; if (lastRoute && lastRoute.url === ev.url) { this.backRouteTrail = this.routeTrail.pop(); } else { this.routeTrail.push({ scroll: { x: this._window.scrollX, y: this._window.scrollY, }, url: ev.url, }); } } else if (ev instanceof NavigationEnd) { if (this.backRouteTrail) { setTimeout(() => { // Give time angular view to render this._window.scrollTo( this.backRouteTrail.scroll.x, this.backRouteTrail.scroll.y, ); this.backRouteTrail = null; }); } else { this._window.scrollTo(0, 0); } } }); } }