在我的Angular 2应用中,当我向下滚动页面并单击页面底部的链接时,它确实会改变路由并将我带到下一页,但它不会滚动到页面顶部。因此,如果第一页很长,第二页内容很少,就会给人一种第二页缺乏内容的印象。因为只有当用户滚动到页面顶部时,内容才可见。
我可以滚动窗口到ngInit组件的页面顶部,但是,有没有更好的解决方案,可以自动处理我的应用程序中的所有路由?
在我的Angular 2应用中,当我向下滚动页面并单击页面底部的链接时,它确实会改变路由并将我带到下一页,但它不会滚动到页面顶部。因此,如果第一页很长,第二页内容很少,就会给人一种第二页缺乏内容的印象。因为只有当用户滚动到页面顶部时,内容才可见。
我可以滚动窗口到ngInit组件的页面顶部,但是,有没有更好的解决方案,可以自动处理我的应用程序中的所有路由?
当前回答
Here's a solution that I've come up with. I paired up the LocationStrategy with the Router events. Using the LocationStrategy to set a boolean to know when a user's currently traversing through the browser history. This way, I don't have to store a bunch of URL and y-scroll data (which doesn't work well anyway, since each data is replaced based on URL). This also solves the edge case when a user decides to hold the back or forward button on a browser and goes back or forward multiple pages rather than just one.
附注:我只测试了最新版本的IE、Chrome、FireFox、Safari和Opera(截至本文)。
希望这能有所帮助。
export class AppComponent implements OnInit {
isPopState = false;
constructor(private router: Router, private locStrat: LocationStrategy) { }
ngOnInit(): void {
this.locStrat.onPopState(() => {
this.isPopState = true;
});
this.router.events.subscribe(event => {
// Scroll to top if accessing a page, not via browser history stack
if (event instanceof NavigationEnd && !this.isPopState) {
window.scrollTo(0, 0);
this.isPopState = false;
}
// Ensures that isPopState is reset
if (event instanceof NavigationEnd) {
this.isPopState = false;
}
});
}
}
其他回答
如果你只是需要滚动页面到顶部,你可以这样做(不是最好的解决方案,但很快)
document.getElementById('elementId').scrollTop = 0;
您可以在主组件上注册路由更改侦听器,并在路由更改时滚动到顶部。
import { Component, OnInit } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
@Component({
selector: 'my-app',
template: '<ng-content></ng-content>',
})
export class MyAppComponent implements OnInit {
constructor(private router: Router) { }
ngOnInit() {
this.router.events.subscribe((evt) => {
if (!(evt instanceof NavigationEnd)) {
return;
}
window.scrollTo(0, 0)
});
}
}
你也可以在Route.ts中使用scrollOffset。 参考Router ExtraOptions
@NgModule({
imports: [
SomeModule.forRoot(
SomeRouting,
{
scrollPositionRestoration: 'enabled',
scrollOffset:[0,0]
})],
exports: [RouterModule]
})
如果你用相同的路径加载不同的组件,那么你可以使用ViewportScroller来实现同样的事情。
import { ViewportScroller } from '@angular/common';
constructor(private viewportScroller: ViewportScroller) {}
this.viewportScroller.scrollToPosition([0, 0]);
从Angular 6.1开始,路由器提供了一个名为scrollPositionRestoration的配置选项,这是为了满足这种情况而设计的。
imports: [
RouterModule.forRoot(routes, {
scrollPositionRestoration: 'enabled'
}),
...
]