我将通过在Angular应用程序中为实现完全相同的目的在线回答几个问题来作为开头。但是,这些似乎都不对我有用。 到目前为止,我已经尝试了这些问题的几乎所有方法 1,2,3,4和其他几个,但我仍然没有得到正确的行为。
当前,如果我向下滚动并查看路线,则单击该项目以通过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
属性单击路由时“重置”滚动位置,以便在加载路由时页面不会停留在相同的滚动位置?
答案 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”。由于固定的标题位于主体的顶部,因此它一直一直处于“顶部”滚动位置。为了解决这个问题,我添加了以下简单代码:
...
<mat-sidenav-content id="detail">
<router-outlet (activate)="resetPosition();"></router-outlet>
</mat-sidenav-content>
...
请注意,(activate)="resetPosition();
使该功能在路由器激活时(或在您使用新路由器时)都运行。这是添加到app.component.ts
的函数:
resetPosition() {
let myDiv = document.getElementById("detail");
myDiv.scrollTop = 0;
}
这将从html容器中获取id="detail"
,然后将滚动位置设置到此 div 的顶部,而不是已位于顶部的整个正文。