在我的Angular 2应用中,当我向下滚动页面并单击页面底部的链接时,它确实会改变路由并将我带到下一页,但它不会滚动到页面顶部。因此,如果第一页很长,第二页内容很少,就会给人一种第二页缺乏内容的印象。因为只有当用户滚动到页面顶部时,内容才可见。

我可以滚动窗口到ngInit组件的页面顶部,但是,有没有更好的解决方案,可以自动处理我的应用程序中的所有路由?


当前回答

@Fernando埃切维里亚 太棒了!但是这段代码不能在哈希路由器或惰性路由器中工作。因为它们不会触发位置更改。 可以试试这个:

private lastRouteUrl: string[] = [] ngOnInit(): void { This.router.events.subscribe ((ev) => { const len = this.lastRouteUrl.length if (ev instanceof NavigationEnd) { this.lastRouteUrl.push (ev.url) If (len > 1 && ev。Url === this。lastRouteUrl[len - 2]) { 返回 } 窗口。scrollTo (0, 0) } }) }

其他回答

如果你只是需要滚动页面到顶部,你可以这样做(不是最好的解决方案,但很快)

document.getElementById('elementId').scrollTop = 0;

你也可以在Route.ts中使用scrollOffset。 参考Router ExtraOptions

@NgModule({
  imports: [
    SomeModule.forRoot(
      SomeRouting,
      {
        scrollPositionRestoration: 'enabled',
        scrollOffset:[0,0]
      })],
  exports: [RouterModule]
})

对于每个正在寻找解决方案并阅读这篇文章的人。的

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

并没有回答这个主题的问题。如果我们查看Angular的源代码,我们会看到一些有趣的行:

这个东西只对反向导航有用。其中一个解决方案可能是:

constructor(router: Router) {

    router.events
        .pipe(filter((e): e is NavigationEnd => e instanceof NavigationEnd))
        .subscribe(() => {
            this.document.querySelector('#top').scrollIntoView();
        });
}

这将查看每个导航到该id的div并滚动到它;

另一种方法是使用相同的逻辑,但在decorator或指令的帮助下,允许你选择何时何地滚动顶部;

如果您使用服务器端呈现,则应该注意不要在服务器上使用窗口运行代码,因为服务器上不存在该变量。这将导致代码被破坏。

export class AppComponent implements OnInit {
  routerSubscription: Subscription;

  constructor(private router: Router,
              @Inject(PLATFORM_ID) private platformId: any) {}

  ngOnInit() {
    if (isPlatformBrowser(this.platformId)) {
      this.routerSubscription = this.router.events
        .filter(event => event instanceof NavigationEnd)
        .subscribe(event => {
          window.scrollTo(0, 0);
        });
    }
  }

  ngOnDestroy() {
    this.routerSubscription.unsubscribe();
  }
}

isPlatformBrowser是一个函数,用于检查当前应用程序所呈现的平台是否是浏览器。我们给它注入platformId。

它也可以检查变量窗口的存在,为了安全起见,像这样:

if (typeof window != 'undefined')

你可以利用observable filter方法更简洁地写这个:

this.router.events.filter(event => event instanceof NavigationEnd).subscribe(() => {
      this.window.scrollTo(0, 0);
});

如果你在使用Angular Material 2 sidenav时遇到滚动到顶部的问题,这将有所帮助。窗口或文档主体不会有滚动条,因此您需要获得sidenav内容容器并滚动该元素,否则尝试将滚动窗口作为默认值。

this.router.events.filter(event => event instanceof NavigationEnd)
  .subscribe(() => {
      const contentContainer = document.querySelector('.mat-sidenav-content') || this.window;
      contentContainer.scrollTo(0, 0);
});

还有,Angular CDK v6。X现在有一个滚动包,可以帮助处理滚动。