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

早过忘川 提交于 2019-12-02 16:19:41

问题


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 position when I press the browser back button.

I'm unable to use Router's scrollPositionRestoration method as it is located in my child component.

Appreciate your help!


回答1:


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!



来源:https://stackoverflow.com/questions/57214772/angular-8-restore-scroll-position-when-browser-back-button-is-selected-in-child

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!