Angular 8: Restore scroll position when browser back button is selected in child component

后端 未结 2 1064
独厮守ぢ
独厮守ぢ 2021-01-24 06:03

I have a component consisting of a list of many cards (like a grid format). Upon scrolling down and selecting one of the cards, I would expect to return to the same scroll posit

相关标签:
2条回答
  • 2021-01-24 06:52

    I was able to make it work by adding

    { scrollPositionRestoration: 'top' } to the RouterModule.forRoot(routes) like this:

    RouterModule.forRoot(routes, { scrollPositionRestoration: 'top' })
    

    And it worked 100%

    0 讨论(0)
  • 2021-01-24 06:56

    Okay I found a solution after reading Angular 2 Scroll to top on Route Change. I just added a window.setTimeout as a temporary fix, even though I don't think it's the best solution.

    import { NavigationStart, Router } from "@angular/router";
    import { Location, PopStateEvent } from "@angular/common";
    import { OnInit } from "@angular/core";
    
    export class xxxComponent implements OnInit {
        lastPoppedUrl = "";
        yScrollStack: number[] = [];
    
        constructor(private location: Location, private router: Router) {
            this.location.subscribe((ev: PopStateEvent) => {
                this.lastPoppedUrl = ev.url;
            });
    
            this.router.events.subscribe((ev: any) => {
                if (ev instanceof NavigationStart) {
                    if (ev.url !== this.lastPoppedUrl) {
                        this.yScrollStack.push(window.scrollY);
                    } else {
                        this.lastPoppedUrl = undefined;
                        window.setTimeout(() => {
                            window.scrollTo(0, this.yScrollStack.pop());
                        }, 300);
                    }
                }
            });
        }
    }
    

    UPDATE (4th Oct 2019)

    My page lazy loads its contents. I've update my code to the following:

    this.location.subscribe((ev: PopStateEvent) => {
      this.lastPoppedUrl = ev.url;
    });
    this.router.events.subscribe((ev: any) => {
      if (ev instanceof NavigationStart) {
        if (ev.url !== this.lastPoppedUrl) {
          this.yScrollStack.push(window.scrollY);
        } else {
          this.lastPoppedUrl = undefined;
          const yposition = this.yScrollStack.pop();
          let maxInterval = 0; // used to stop subscription
          interval(this.scrollInterval)
            .pipe(
              takeWhile(_ => window.scrollY < yposition && maxInterval < 5000)
            )
            .subscribe(_ => {
              maxInterval += this.scrollInterval;
              window.scrollTo({
                top: yposition,
                left: 0,
                behavior: 'smooth',
              });
            });
        }
      }
    });
    

    Let me know if there are any better solution out there. If the user can immediately return to the same position of the previous page instead of scrolling downwards that would be best, thanks!

    0 讨论(0)
提交回复
热议问题