jtbitt
jtbitt

Reputation: 581

window.scrollTo(0, 0) and scrollTop = 0 not working on Angular 2 route changes

This is an extremely frustrating issue. I'm done with my application other then this one last thing. I've been listening for changes on the router, and trying to have it autoscroll to the top upon that change. I've literally tried 10 different solutions on Google and nothing has any effect. I know it's related to the router, but I can't figure out why exactly it won't scroll. Here is the code I'm currently using.

app.component.ts

this.router.events.filter(event => event instanceof NavigationEnd).subscribe(event => {
  window.scroll(0, 0);
});

app.component.html

<div class="mainbody bgc-white">
  <router-outlet></router-outlet>
</div>

I've tried several variations of this, specifically grabbing the router-outlet element with ElementRef and setting scrollTop = 0, but that had no effect either. Also tried using document.body and that had no effect. What am I missing here?

Upvotes: 8

Views: 7982

Answers (4)

Harshit Singhal
Harshit Singhal

Reputation: 21

Add this to your app.component is using router-outlet

 ngOnInit() {
    this.routerSubscription = this.router.events.pipe(
      filter(event => event instanceof NavigationEnd)
    )
      .subscribe(() => {
        document.querySelector('mat-drawer-content').scrollTop = 0;
      });
  }

  ngOnDestroy() {
    this.routerSubscription.unsubscribe();
  }

Upvotes: 2

ole
ole

Reputation: 71

I've just managed to fix the same problem with a setTimeout hack like so:

scrollToTop(): void {
  setTimeout(() => window.scroll(0, 0), 0);
}

Upvotes: 6

Rohan Kumar
Rohan Kumar

Reputation: 40639

Yes I am using Angular 5 and the same code which you have used did not work, so I have used the below code which works well either,

this.router.events.subscribe(evt => {
    if (evt instanceof NavigationEnd) {
         document.body.scrollTop = 0; // scroll top to body element
    }
});

Upvotes: 1

jtbitt
jtbitt

Reputation: 581

Finally was able to get this working. Nothing else was working for me.

I had to create this scroll service: https://github.com/angular/angular/blob/master/aio/src/app/shared/scroll.service.ts

Then inject it into each individual page that I wanted to autoscroll to the top, then call it in the page like so.

ngAfterViewInit() {
  [your scroll service].scrollToTop();
}

Also had to put this id (this is what the service uses) on the div around my router-outlet, as opposed to the body. When I was targeting the body tag, the scroll was doing nothing. When I targeted the div right outside the router-outlet, it worked.

<div id="top-of-page">
  <router-outlet></router-outlet>
</div>

I got this solution from the page linked by BogdanC, but had to modify it to work in my situation.

Upvotes: 3

Related Questions