Angular 2滚动到路线更改顶部时不起作用

时间:2018-11-07 01:37:00

标签: javascript jquery angular

当路线更改时,我试图滚动到我的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)
        });
    }
}

我在做什么错了?

6 个答案:

答案 0 :(得分:13)

当新组件加载到<router-outlet>中时,路由器将发出一个事件,以便您可以向其附加事件。

因此在带有<router-outlet>的组件中使用:

<router-outlet (activate)="scrollTop($event)">

,然后在放置<router-outlet>的相同组件中添加以下方法:

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

答案 1 :(得分:2)

在开始滚动之前,请等待组件初始化。因此最好将此代码放在ngAfterViewInit函数下。

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

答案 2 :(得分:2)

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

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

  }
}

答案 3 :(得分:2)

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

答案 4 :(得分:2)

此解决方案在我的项目中非常有效:

Max

答案 5 :(得分:0)

对我而言,在Angular 10.2.x上唯一适用的解决方案是使用setTimeout持续190毫秒!如果我将计时器设置为190ms以下,则无法滚动!

当我将计时器设置为300ms时,我可以看到路由之后,页面如何首先通过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);
  }
}