Угловой 5 Прокрутите вверх на каждый щелчок маршрута

Я использую угловой 5. У меня есть панель инструментов, где у меня есть несколько разделов с небольшим контентом и несколько разделов с таким большим содержимым, с которыми мне приходится сталкиваться при изменении роутера при переходе на верх. Каждый раз, когда мне нужно прокручивать, чтобы перейти наверх. Может ли кто-нибудь помочь мне решить эту проблему, чтобы при изменении маршрутизатора мой взгляд всегда оставался на вершине.

Заранее спасибо.

Ответ 1

Розетка маршрутизатора будет генерировать событие активации каждый раз, когда создается новый компонент, поэтому (activate) событие может состоять в прокрутке (например) вверх:

app.component.html

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

app.component.ts

onActivate(event) {
    window.scroll(0,0);
    //or document.body.scrollTop = 0;
    //or document.querySelector('body').scrollTo(0,0)
    ...
}

или используя этот ответ для плавной прокрутки

    onActivate(event) {
        let scrollToTop = window.setInterval(() => {
            let pos = window.pageYOffset;
            if (pos > 0) {
                window.scrollTo(0, pos - 20); // how far to scroll on each step
            } else {
                window.clearInterval(scrollToTop);
            }
        }, 16);
    }

Если вы хотите быть избирательным, скажем, не каждый компонент должен запускать прокрутку, вы можете проверить это:

onActivate(e) {
    if (e.constructor.name)==="login"{ // for example
            window.scroll(0,0);
    }
}


Начиная с Angular6.1, мы также можем использовать { scrollPositionRestoration: 'enabled' } на загруженных модулях или только в app.module, и это будет применяться ко всем маршрутам:
RouterModule.forRoot(appRoutes, { scrollPositionRestoration: 'enabled' })

Это также сделает плавную прокрутку

Ответ 2

Если вы столкнулись с этой проблемой в Angular 6, вы можете исправить ее, добавив параметр scrollPositionRestoration: 'enabled' в app-routing.module.ts RouterModule:

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

Ответ 3

РЕДАКТИРОВАТЬ: Для Angular 6+, пожалуйста, используйте ответ Nimesh Nishara Indimagedara с упоминанием:

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

Оригинальный ответ:

Если все не удается, создайте пустой элемент HTML (например, div) вверху (или нужную прокрутку до местоположения) с id = "top" в шаблоне (или родительском шаблоне):

<div id="top"></div>

И в компоненте:

  ngAfterViewInit() {
    // Hack: Scrolls to top of Page after page view initialized
    let top = document.getElementById('top');
    if (top !== null) {
      top.scrollIntoView();
      top = null;
    }
  }

Ответ 5

Хотя @Vega обеспечивает прямой ответ на ваш вопрос, есть проблемы. Он разбивает кнопку браузера назад/вперед. Если вы нажимаете кнопку браузера назад или вперед, они теряют свое место и прокручиваются вверху. Это может быть немного болью для ваших пользователей, если им пришлось прокручивать путь вниз, чтобы добраться до ссылки, и решил щелкнуть назад, только чтобы найти полосу прокрутки, сброшенную вверх.

Вот мое решение проблемы.

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

Ответ 6

В моем случае я просто добавил

window.scroll(0,0);

в ngOnInit() и его работе.

Ответ 7

От angular версии 6+ Нет необходимости использовать window.scroll(0,0)

Для angular версии 6+ от @docs
Представляет параметры для настройки маршрутизатора.

interface ExtraOptions {
  enableTracing?: boolean
  useHash?: boolean
  initialNavigation?: InitialNavigation
  errorHandler?: ErrorHandler
  preloadingStrategy?: any
  onSameUrlNavigation?: 'reload' | 'ignore'
  scrollPositionRestoration?: 'disabled' | 'enabled' | 'top'
  anchorScrolling?: 'disabled' | 'enabled'
  scrollOffset?: [number, number] | (() => [number, number])
  paramsInheritanceStrategy?: 'emptyOnly' | 'always'
  malformedUriErrorHandler?: (error: URIError, urlSerializer: UrlSerializer, url: string) => UrlTree
  urlUpdateStrategy?: 'deferred' | 'eager'
  relativeLinkResolution?: 'legacy' | 'corrected'
}

Можно использовать scrollPositionRestoration?: 'disabled' | 'enabled' | 'top' в

Пример:

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

И если требуется вручную прокрутить прокрутку, нет необходимости использовать window.scroll(0,0) Вместо Angular V6 общий пакет представил ViewPortScoller.

abstract class ViewportScroller {
  static ngInjectableDef: defineInjectable({ providedIn: 'root', factory: () => new BrowserViewportScroller(inject(DOCUMENT), window) })
  abstract setOffset(offset: [number, number] | (() => [number, number])): void
  abstract getScrollPosition(): [number, number]
  abstract scrollToPosition(position: [number, number]): void
  abstract scrollToAnchor(anchor: string): void
  abstract setHistoryScrollRestoration(scrollRestoration: 'auto' | 'manual'): void
}

Использование довольно просто Пример:

import { Router } from '@angular/router';
import {  ViewportScroller } from '@angular/common'; //import
export class RouteService {

  private applicationInitialRoutes: Routes;
  constructor(
    private router: Router;
    private viewPortScroller: ViewportScroller//inject
  )
  {
   this.router.events.pipe(
            filter(event => event instanceof NavigationEnd))
            .subscribe(() => this.viewPortScroller.scrollToPosition([0, 0]));
}

Ответ 8

Вот решение, которое только прокручивается к вершине Компонента при первом посещении для КАЖДОГО компонента (в случае, если вам нужно сделать что-то другое для каждого компонента):

В каждом компоненте:

export class MyComponent implements OnInit {

firstLoad: boolean = true;

...

ngOnInit() {

  if(this.firstLoad) {
    window.scroll(0,0);
    this.firstLoad = false;
  }
  ...
}

Ответ 9

Я продолжаю искать встроенное решение этой проблемы, как в AngularJS. Но до тех пор это решение работает для меня, оно простое и сохраняет функциональность кнопки "Назад".

app.component.html

<router-outlet (deactivate)="onDeactivate()"></router-outlet>

app.component.ts

onDeactivate() {
  document.body.scrollTop = 0;
  // Alternatively, you can scroll to top by using this other call:
  // window.scrollTo(0, 0)
}

Ответ от оригинала оригинала zurfyx

Ответ 10

Вам просто нужно создать функцию, которая содержит настройку прокрутки экрана

например

window.scroll(0,0) OR window.scrollTo() by passing appropriate parameter.

window.scrollTo(xpos, ypos) → ожидаемый параметр.

Ответ 11

Попробуй это:

app.component.ts

import {Component, OnInit, OnDestroy} from '@angular/core';
import {Router, NavigationEnd} from '@angular/router';
import {filter} from 'rxjs/operators';
import {Subscription} from 'rxjs';

@Component({
    selector: 'app-root',
    templateUrl: './app.component.html',
    styleUrls: ['./app.component.scss'],
})
export class AppComponent implements OnInit, OnDestroy {
    subscription: Subscription;

    constructor(private router: Router) {
    }

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

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

Ответ 12

export class AppComponent {
  constructor(private router: Router) {
    router.events.subscribe((val) => {
      if (val instanceof NavigationEnd) {
        window.scrollTo(0, 0);
      }
    });
  }

}

Ответ 13

Компонент: подписывайтесь на все события маршрутизации вместо создания действия в шаблоне и прокручивайте NavigationEnd b/c, в противном случае вы отключите его на плохих навигационных или заблокированных маршрутах и т.д. Это верный способ узнать, что если маршрут успешно пройден, затем прокрутите страницу. В противном случае ничего не делать.

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit, OnDestroy {

  router$: Subscription;

  constructor(private router: Router) {}

  ngOnInit() {
    this.router$ = this.router.events.subscribe(next => this.onRouteUpdated(next));
  }

  ngOnDestroy() {
    if (this.router$ != null) {
      this.router$.unsubscribe();
    }
  }

  private onRouteUpdated(event: any): void {
    if (event instanceof NavigationEnd) {
      this.smoothScrollTop();
    }
  }

  private smoothScrollTop(): void {
    const scrollToTop = window.setInterval(() => {
      const pos: number = window.pageYOffset;
      if (pos > 0) {
          window.scrollTo(0, pos - 20); // how far to scroll on each step
      } else {
          window.clearInterval(scrollToTop);
      }
    }, 16);
  }

}

HTML

<router-outlet></router-outlet>

Ответ 14

попробуйте это

@NgModule({
  imports: [RouterModule.forRoot(routes,{
    scrollPositionRestoration: 'top'
  })],
  exports: [RouterModule]
})

этот код поддерживает angular 6 & lt; =

Ответ 15

Angular 6.1 и более поздние версии:

Вы можете использовать встроенное решение, доступное в Angular 6. 1+ с опцией scrollPositionRestoration: 'enabled', чтобы добиться того же.

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

Angular 6.0 и более ранние версии:

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

Примечание. Ожидаемое поведение заключается в том, что при переходе обратно на страницу она должна оставаться прокручиваемой вниз до того же места, в котором она была при нажатии на ссылку, но прокручиваться до самого верха при переходе на каждую страницу.