Я использую angular 5. У меня есть панель инструментов, где у меня есть несколько разделов с небольшим содержанием и несколько разделов с таким большим содержанием, что я сталкиваюсь с проблемой при смене маршрутизатора при переходе наверх. Каждый раз мне нужно прокрутить, чтобы перейти наверх. Может ли кто-нибудь помочь мне решить эту проблему, чтобы при смене маршрутизатора мое мнение всегда оставалось наверху.
Заранее спасибо.
Ответы:
Есть несколько решений, обязательно проверьте их все :)
Выход маршрутизатора будет генерировать
activate
событие каждый раз, когда создается новый компонент, поэтому мы могли бы использовать(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); }
Если вы хотите быть избирательным, скажем, не каждый компонент должен запускать прокрутку, вы можете проверить это с помощью такого
if
оператора:onActivate(e) { if (e.constructor.name)==="login"{ // for example window.scroll(0,0); } }
Начиная с Angular6.1, мы также можем использовать
{ scrollPositionRestoration: 'enabled' }
для загруженных модулей, и это будет применяться ко всем маршрутам:RouterModule.forRoot(appRoutes, { scrollPositionRestoration: 'enabled' })
Он также будет выполнять плавную прокрутку. Однако это неудобно делать на любой маршрутизации.
Другое решение - сделать верхнюю прокрутку анимации маршрутизатора. Добавьте это в каждый переход, где вы хотите прокрутить вверх:
query(':enter, :leave', style({ position: 'fixed' }), { optional: true })
источник
window
объекта не работают в angular 5. Есть предположения, почему?Если вы столкнулись с этой проблемой в Angular 6, вы можете исправить ее, добавив параметр
scrollPositionRestoration: 'enabled'
в RouterModule app-routing.module.ts:@NgModule({ imports: [RouterModule.forRoot(routes,{ scrollPositionRestoration: 'enabled' })], exports: [RouterModule] })
источник
scrollPositionRestoration
свойство не работает с динамическим содержимым страницы (то есть, когда содержимое страницы загружается асинхронно): см. Этот отчет об ошибке Angular: github.com/angular/angular / issues / 24547РЕДАКТИРОВАТЬ: для 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; } }
источник
Теперь в Angular 6.1 доступно встроенное решение с
scrollPositionRestoration
опцией.См. Мой ответ по Angular 2. Прокрутите вверх в разделе « Изменение маршрута» .
источник
Хотя @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; } }); } }
источник
В моем случае я просто добавил
window.scroll(0,0);
in
ngOnInit()
и работает нормально.источник
Начиная с 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 V6ViewPortScoller
.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])); }
источник
если вы используете mat-sidenav, укажите идентификатор для выхода маршрутизатора (если у вас есть родительский и дочерний выходы маршрутизатора) и используйте в нем функцию активации
<router-outlet id="main-content" (activate)="onActivate($event)">
и используйте этот селектор запросов mat-sidenav-content для прокрутки вверхonActivate(event) { document.querySelector("mat-sidenav-content").scrollTo(0, 0); }
источник
id
(вrouter-outlet
моем приложении есть сингл ). Я также сделал это более «угловатым способом»:@ViewChild(MatSidenavContainer) sidenavContainer: MatSidenavContainer; onActivate() { this.sidenavContainer.scrollable.scrollTo({ left: 0, top: 0 }); }
Я продолжаю искать встроенное решение этой проблемы, как в 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
источник
Вам просто нужно создать функцию, которая содержит настройку прокрутки вашего экрана.
например
window.scroll(0,0) OR window.scrollTo() by passing appropriate parameter.
window.scrollTo (xpos, ypos) -> ожидаемый параметр.
источник
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); } }); } }
Примечание . Ожидаемое поведение заключается в том, что когда вы переходите обратно на страницу, она должна оставаться прокрученной вниз до того же места, что и при нажатии на ссылку, но с прокруткой вверх при переходе на каждую страницу.
источник
Вот решение, которое прокручивается в начало компонента только при первом посещении КАЖДОГО компонента (в случае, если вам нужно сделать что-то другое для каждого компонента):
В каждом компоненте:
export class MyComponent implements OnInit { firstLoad: boolean = true; ... ngOnInit() { if(this.firstLoad) { window.scroll(0,0); this.firstLoad = false; } ... }
источник
export class AppComponent { constructor(private router: Router) { router.events.subscribe((val) => { if (val instanceof NavigationEnd) { window.scrollTo(0, 0); } }); } }
источник
просто добавь
window.scrollTo({ top: 0);
в ngOnInit ()
источник
Для тех, кто ищет функцию прокрутки, просто добавьте функцию и вызовите, когда когда-либо понадобится
scrollbarTop(){ window.scroll(0,0); }
источник
Попробуй это:
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(); } }
источник
Компонент: подпишитесь на все события маршрутизации вместо создания действия в шаблоне и прокрутите 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
источник
попробуй это
@NgModule({ imports: [RouterModule.forRoot(routes,{ scrollPositionRestoration: 'top' })], exports: [RouterModule] })
этот код поддерживает угловой 6 <=
источник