Angular 2在路线更改上滚动到顶部

新手上路,请多包涵

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

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

原文由 Naveed Ahmed 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.3k
2 个回答

Angular 6.1 及更高版本

Angular 6.1(于 2018-07-25 发布)通过称为“路由器滚动位置恢复”的功能添加了内置支持来处理此问题。如官方 Angular 博客 中所述,您只需在路由器配置中启用此功能,如下所示:

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

此外,该博客指出“预计这将成为未来主要版本的默认设置”。到目前为止,这还没有发生(从 Angular 11.0 开始),但最终您根本不需要在代码中做任何事情,而且开箱即用就可以正常工作。

您可以在 官方文档 中查看有关此功能以及如何自定义此行为的更多详细信息。

Angular 6.0 及更早版本

虽然@GuilhermeMeireles 的出色答案解决了原始问题,但它引入了一个新问题,它打破了您在向后或向前导航时所期望的正常行为(使用浏览器按钮或通过代码中的位置)。预期的行为是,当您导航回页面时,它应该保持向下滚动到单击链接时的相同位置,但是在到达每个页面时滚动到顶部显然打破了这种期望。

下面的代码扩展了检测这种导航的逻辑,方法是订阅 Location 的 PopStateEvent 序列,如果新到达的页面是此类事件的结果,则跳过滚动到顶部的逻辑。

如果您从导航返回的页面足够长以覆盖整个视口,则滚动位置会自动恢复,但正如@JordanNelson 正确指出的那样,如果页面较短,您需要跟踪原始 y 滚动位置并恢复它返回页面时明确显示。代码的更新版本也涵盖了这种情况,始终显式恢复滚动位置。

 import { Component, OnInit } from '@angular/core';
import { Router, NavigationStart, NavigationEnd } from '@angular/router';
import { Location, PopStateEvent } from "@angular/common";

@Component({
    selector: 'my-app',
    template: '<ng-content></ng-content>',
})
export class MyAppComponent implements OnInit {

    private lastPoppedUrl: string;
    private yScrollStack: number[] = [];

    constructor(private router: Router, private location: Location) { }

    ngOnInit() {
        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 if (ev instanceof NavigationEnd) {
                if (ev.url == this.lastPoppedUrl) {
                    this.lastPoppedUrl = undefined;
                    window.scrollTo(0, this.yScrollStack.pop());
                } else
                    window.scrollTo(0, 0);
            }
        });
    }
}

原文由 Fernando Echeverria 发布,翻译遵循 CC BY-SA 4.0 许可协议

在执行时在下面调用它,它为我工作 %100

   document.body.scrollTop = 0;

 this.brandCollectionList$.subscribe((response) => {
  document.body.scrollTop = 0;

});

原文由 Karwan E. Othman 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进