【问题标题】:Angular 2 scroll to top on route change not workingAngular 2在路线更改不起作用时滚动到顶部
【发布时间】:2018-11-07 01:37:00
【问题描述】:

当路线更改时,我试图滚动到我的 angular 2 站点上的页面顶部,我尝试了以下操作,但没有任何反应,当我将路线从一页更改为另一页时,页面滚动到它在第一页的位置:

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)
        });
    }
}

我做错了什么?

【问题讨论】:

  • 试试setTimeout(function () {window.scrollTo(0, 300);},2)
  • 不,这不起作用,我的控制台日志中没有错误。
  • 我试过它对我有用。其他选项是使用 jquery $('#content').animate({ scrollTop: 20 }, 200)
  • 还是不行,烦人
  • 你能提供一个stackblitz来显示这个问题吗?

标签: javascript jquery angular


【解决方案1】:

&lt;router-outlet&gt; 中加载新组件时,路由器将发出一个事件,以便您可以将事件附加到它。

所以在你的组件中使用&lt;router-outlet&gt;

&lt;router-outlet (activate)="scrollTop($event)"&gt;

然后在你放置&lt;router-outlet&gt;的同一个组件中添加以下方法:

scrollTop(event) {
  window.scroll(0,0);
}

【讨论】:

  • 我试过了,scrollTop 在每个页面上都被调用,但它没有滚动到页面顶部。
  • 实际上,这确实有效,但只有当我删除 height: 100% to body
  • 这个答案似乎是正确的,先做一些测试。
【解决方案2】:

在开始滚动之前等待组件初始化组件。所以最好把这段代码放在ngAfterViewInit函数下。

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

【讨论】:

  • 现在试试这个。
  • 将日志放在window.scrollTo(0, 0)之前,检查是否被执行。我怀疑 return 语句正在被执行。
  • 我在window.scrollTo(0, 0) 之前放了一个console.log,它没有被执行
  • 等一下,控制台日志正在执行中。
【解决方案3】:

我遇到了类似的问题,这是由于应用于 body 的样式。 即

body {
    height: 100%;
    overflow-x: hidden;
}

如果我删除了这种样式,那么我的布局就会受到严重影响。

我没有删除样式,而是尝试了下面的解决方案,它对我有用...

解决办法:

export class AppComponent implements OnInit {


  constructor(private router: Router, private changeDetect: ChangeDetectorRef) {
  }

  ngOnInit() {
    this.router.events.subscribe((evt) => {
      if (!(evt instanceof NavigationEnd)) {
        return;
      }
      // Change height:100% into auto
      $('body').css('height', 'auto');
      // Successfully scroll back to top
      $('body').scrollTop(0);
      // Remove javascript added styles
      $('body').css('height', '');
      this.changeDetect.detectChanges();
    });

  }
}

【讨论】:

    【解决方案4】:
      constructor(
        private router: Router,
        private ngZone: NgZone) {
        router.events.subscribe((event: RouterEvent) => {
          this._navigationInterceptor(event);
        });
      }
    
      private _navigationInterceptor(event: RouterEvent): void {
        if (event instanceof NavigationStart) {
        }
        if (event instanceof NavigationEnd) {
        window.scrollTo({
         top: 0
        });
      // or,  window.scroll(0,0);
        }
      }
    

    【讨论】:

      【解决方案5】:

      此解决方案在我的项目中完美运行:

      export class AppComponent  {
        constructor (
          private _router: Router,
        ) {
          this._subscribeRouteEvents();
        }
      
        private _subscribeRouteEvents (): void {
          this._router.events.subscribe(e => {
            if (!(e instanceof NavigationEnd)) return;
            window.scrollTo(0, 0);
          });
        }
      }
      

      【讨论】:

        【解决方案6】:

        在 Angular 10.2.x 上对我有用的唯一解决方案是使用 setTimeout 190 毫秒,不少于!如果我将定时器设置在 190 毫秒以下,滚动将不起作用!

        当我将计时器设置为 300 毫秒时,我可以看到,在路由之后,页面如何首先通过 Angular 路由器滚动到我不需要的位置,然后页面滚动到 0,这是应该的。我仍然不明白为什么 Angular 在路由到页面后会进行不必要的滚动。

        我尝试了不同的建议解决方案。比如改变 scrollPositionRestoration 属性的值,在 AfterViewInit 钩子中执行强制滚动,改变 body 标签的全局高度,但只有这样才有帮助。这很可能是 Angular 10.2.x 路由器中的某种错误

        constructor(
          private router: Router,
        ) {
          router.events.subscribe(event => {
          if (event instanceof NavigationEnd) {
            setTimeout(() => {
              document.documentElement.scrollTop = 0; // || window.scrollTo(0, 0);
            }, 190);
          }
        }
        

        【讨论】:

          猜你喜欢
          • 2021-12-15
          • 2014-01-30
          • 2019-11-19
          • 2020-10-01
          • 2019-08-25
          • 2018-06-11
          • 2015-10-25
          • 1970-01-01
          相关资源
          最近更新 更多