import {ActivationStart, NavigationEnd, Router} from '@angular/router'; import {Injectable, Type} from '@angular/core'; import {Subscription} from 'rxjs'; @Injectable({ providedIn: 'root' }) export class SmoothScroll { private interval; private readonly sub; private lastComponent; private currentComponent: string; constructor(private router: Router) { if (typeof window !== "undefined") { this.sub = router.events.subscribe(event => { if (event instanceof ActivationStart) { if(event.snapshot.component instanceof Type) { this.currentComponent = event.snapshot.component.name; } } else if (event instanceof NavigationEnd) { if (this.interval) { clearInterval(this.interval); } const fragment = router.parseUrl(router.url).fragment; if (this.lastComponent !== this.currentComponent) { window.scrollTo({top: 0}); } if (fragment) { let i = 0; this.interval = setInterval(() => { i++; const element = document.getElementById(fragment); if (element) { if (this.interval) { clearInterval(this.interval); } const yOffset = -100; let position = 0; let interval = setInterval(() => { if (position !== element.getBoundingClientRect().top) { position = element.getBoundingClientRect().top; } else { clearInterval(interval); const y = element.getBoundingClientRect().top + window.pageYOffset + yOffset; window.scrollTo({top: y, behavior: 'smooth'}); } }, 50); } if (i > 4 && this.interval) { clearInterval(this.interval); } }, 100); } else { setTimeout( () => { window.scrollTo({top: 0, behavior: 'smooth'}); }, 0); } this.lastComponent = this.currentComponent; } }); } } public clearSubscriptions() { if (this.sub && this.sub instanceof Subscription) { this.sub.unsubscribe(); } if (this.interval) { clearInterval(this.interval); } } }