Угловой 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;
}
}
Ответ 4
Теперь есть встроенное решение, доступное в Angular 6.1 с параметром scrollPositionRestoration
.
См. Мой ответ на " Угловой 2". Прокрутите вверх до пункта "Изменение маршрута".
Ответ 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);
}
});
}
}
Примечание. Ожидаемое поведение заключается в том, что при переходе обратно на страницу она должна оставаться прокручиваемой вниз до того же места, в котором она была при нажатии на ссылку, но прокручиваться до самого верха при переходе на каждую страницу.