Make sure to explore all the options available to you :)
Method 1:
When a new component is instantiated in the router outlet, the activate
event is emitted, allowing us to use (activate)
for scrolling purposes like so:
app.component.html
<router-outlet (activate)="onActivate($event)"></router-outlet>
app.component.ts
onActivate(event) {
// window.scroll(0,0);
window.scroll({
top: 0,
left: 0,
behavior: 'smooth'
});
//or document.body.scrollTop = 0;
//or document.querySelector('body').scrollTo(0,0)
...
}
If smooth scroll doesn't work well in Safari, you can try using this solution:
onActivate(event) {
let scrollToTop = window.setInterval(() => {
let pos = window.pageYOffset;
if (pos > 0) {
window.scrollTo(0, pos - 20); // how far to scroll on each step
} else {
window.clearInterval(scrollToTop);
}
}, 16);
}
If you only want certain components to trigger the scrolling, you can check for it in an if
statement like this:
onActivate(e) {
if (e.constructor.name === "login") { // for example
window.scroll(0,0);
}
}
Method 2:
Starting from Angular 6.1, you can also utilize
{ scrollPositionRestoration: 'enabled' }
on eagerly loaded modules to apply it to all routes:
RouterModule.forRoot(appRoutes, { scrollPositionRestoration: 'enabled' })
This method already includes smooth scrolling but will be applied to every routing which may not be suitable in all cases.
Method 3:
Another approach is to implement top scrolling during router animations. Include this in every transition where top scroll is desired:
query(':enter, :leave', style({ position: 'fixed' }), { optional: true })