返回到RouterLink的页面顶部

时间:2020-03-02 22:09:19

标签: javascript angular angular-material

我将通过在Angular应用程序中为实现完全相同的目的在线回答几个问题来作为开头。但是,这些似乎都不对我有用。 到目前为止,我已经尝试了这些问题的几乎所有方法 1234和其他几个,但我仍然没有得到正确的行为。

当前,如果我向下滚动并查看路线,则单击该项目以通过routerLink查看新路线,该页面将保持不变。这会引起一些问题,尤其是在较小的屏幕上或在很长的项目列表中查看时。

在当前应用中,我的AppComponent如下(我正在使用Angular Material):

<app-header></app-header>
<mat-sidenav-container class="main-sidenav">

  <mat-sidenav class="sidenav"#sidenav [mode]="mode" [opened]="openSidenav">
    <app-sidenav></app-sidenav>
  </mat-sidenav>
  <mat-sidenav-content>

    <router-outlet></router-outlet>

  </mat-sidenav-content>
</mat-sidenav-container>

router-outlet显示以下内容之一:

  • 带有列表和过滤器的锻炼页面
  • 显示锻炼说明的锻炼“详细页面”

在锻炼列表中,单击某个项目时,它具有routerLink:<a [routerLink]="[i]">,其中i是来自数组(在本例中为Firebase数据库)的当前锻炼的索引。

Here is the stackblitz to this code.锻炼页面可以在src/app/features/workouts-page/上找到,然后相应地显示锻炼列表,锻炼过滤器和锻炼细节。但是,单击routerLink时,滚动位置在锻炼详细信息页面上保持不变。

自Angular 6+起,建议在路由模块中使用以下方法:

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

同时,您也可以使用“启用”并获得相同的结果。这不会更改我正在运行的应用程序中的任何行为。此外,我尝试了一些“解决方法”,例如将以下内容添加到我的主要组件中:

export class MyAppComponent implements OnInit {
    constructor(private router: Router) { }

    ngOnInit() {
        this.router.events.subscribe((evt) => {
            if (!(evt instanceof NavigationEnd)) {
                return;
            }
            window.scrollTo(0, 0)
        });
    }
}

此替代方法以及许多其他替代方法都没有再次更改行为,它使页面与单击路由器之前相同的滚动位置。与GitHub请求不同的一种方法是将(activate)="onActivate($event)添加到<router-outlet>,函数在其中运行window.scrollTo(0, 0);。不过,这似乎不起作用。我什至可以将window.scrollTo(0,0)scrollTop()放在与路由器插座相关的任何组件的ngOnInit中,您猜对了,仍然没有任何变化。

我认为这完全与页面的CSS有关,因此我按照相同的最终结果更改了堆栈溢出问题中提到的正文和html位置。

有没有一种方法可以在使用routerLink属性单击路由时“重置”滚动位置,以便在加载路由时页面不会停留在相同的滚动位置?

2 个答案:

答案 0 :(得分:1)

ScrollPositionRestoration可以在整页滚动(主体滚动)下正常工作。 在您的情况下,内部div是可滚动的。要为那些用户恢复滚动,您需要自定义滚动恢复过程。 这是一个讨论相同https://www.bennadel.com/blog/3534-restoring-and-resetting-the-scroll-position-using-the-navigationstart-event-in-angular-7-0-4.htm

的博客链接。

基本思想是在导航之前存储滚动位置,如果由于弹出状态而访问页面,则还原滚动位置。

答案 1 :(得分:0)

Nikhil给出了ScrollPositionRestoration的方法,并帮助我找到了此方法不起作用的原因,但最终我找到了一种使用简单的激活函数来实现此目的的方法。

就像他提到的那样,之所以不起作用,是因为在滚动条上重置了“ body”。由于固定的标题位于主体的顶部,因此它一直一直处于“顶部”滚动位置。为了解决这个问题,我添加了以下简单代码:

在AppComponent HTML中

...
  <mat-sidenav-content id="detail">
    <router-outlet (activate)="resetPosition();"></router-outlet>
  </mat-sidenav-content>
...

请注意,(activate)="resetPosition();使该功能在路由器激活时(或在您使用新路由器时)都运行。这是添加到app.component.ts的函数:

AppComponent TS

resetPosition() {
  let myDiv = document.getElementById("detail");
  myDiv.scrollTop = 0;
}

这将从html容器中获取id="detail",然后将滚动位置设置到此 div 的顶部,而不是已位于顶部的整个正文。