rai*_*han 64 javascript scrolltop typescript angular angular-router
我正在使用角度5.我有一个仪表板,我有几个部分内容很少,几个部分内容如此之大,以至于我在更换路由器时遇到问题.每次我需要滚动到顶部.任何人都可以帮助我解决这个问题,以便当我更改路由器时,我的视图始终保持在顶部.
提前致谢.
Veg*_*ega 141
每当实例化新组件时,路由器插座都会发出激活事件,因此(activate)事件可能是滚动(例如)到顶部:
app.component.html
<router-outlet (activate)="onActivate($event)" ></router-outlet>
Run Code Online (Sandbox Code Playgroud)
app.component.ts
onActivate(event) {
window.scroll(0,0);
//or document.body.scrollTop = 0;
//or document.querySelector('body').scrollTo(0,0)
...
}
Run Code Online (Sandbox Code Playgroud)
或使用此答案平滑滚动
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);
}
Run Code Online (Sandbox Code Playgroud)
如果你希望有选择性,说不是每个组件都应该触发滚动,你可以检查它:
onActivate(e) {
if (e.constructor.name)==="login"{ // for example
window.scroll(0,0);
}
}
Run Code Online (Sandbox Code Playgroud)
Nim*_*zzz 40
如果有人在Angular 6中遇到此问题,您可以通过在app-routing.module.ts的RouterModule中添加以下参数来修复它.
复制并粘贴:{scrollPositionRestoration:'enabled'}
Geo*_*ver 19
如果全部失败,则在模板(或父模板)上创建一个空的HTML元素(例如:div)(或者想要滚动到位置),其中id ="top":
RouterModule.forRoot(routes, {
scrollPositionRestoration: 'enabled'
});
Run Code Online (Sandbox Code Playgroud)
在组件中:
<div id="top"></div>
Run Code Online (Sandbox Code Playgroud)
Abd*_*fay 15
现在,Angular 6.1中提供了一个内置解决方案,scrollPositionRestoration可选.
请参阅我对Angular 2的回答滚动到Route Change的顶部.
对于6+来自@
Represents 的Angular 版本,用于配置路由器的选项。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'
}
Run Code Online (Sandbox Code Playgroud)
人们可以使用scrollPositionRestoration?: 'disabled' | 'enabled' | 'top'在
例子:
RouterModule.forRoot(routes, {
scrollPositionRestoration: 'enabled'|'top'
});
Run Code Online (Sandbox Code Playgroud)
如果需要手动控制滚动,无需使用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
}
Run Code Online (Sandbox Code Playgroud)
用法非常简单 示例:
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]));
}
Run Code Online (Sandbox Code Playgroud)
只需在文件中添加这一行app.module.ts:
RouterModule.forRoot(routes, {
scrollPositionRestoration: 'enabled' //scroll to the top
})
Run Code Online (Sandbox Code Playgroud)
我正在使用 Angular 11.1.4,它对我有用
Angular 6.1 及更高版本:
您可以使用Angular 6.1+中提供的内置解决方案以及选项来实现相同的目的。scrollPositionRestoration: 'enabled'
@NgModule({
imports: [RouterModule.forRoot(routes,{
scrollPositionRestoration: 'enabled'
})],
exports: [RouterModule]
})
Run Code Online (Sandbox Code Playgroud)
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);
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
注意:预期的行为是,当您导航回页面时,它应该保持向下滚动到单击链接时的相同位置,但在到达每个页面时滚动到顶部。
尽管@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;
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
小智 5
如果您使用 mat-sidenav 为路由器插座提供 id(如果您有父路由器插座和子路由器插座)并在其中使用激活功能
<router-outlet id="main-content" (activate)="onActivate($event)">
并使用此“mat-sidenav-content”查询选择器滚动顶部
onActivate(event) {
document.querySelector("mat-sidenav-content").scrollTo(0, 0);
}
小智 5
由于某种原因,以上内容都不适合我:/,因此我将元素引用添加到 中的顶部元素app.component.html,并(activate)=onNavigate($event)添加到router-outlet.
<!--app.component.html-->
<div #topScrollAnchor></div>
<app-navbar></app-navbar>
<router-outlet (activate)="onNavigate($event)"></router-outlet>
Run Code Online (Sandbox Code Playgroud)
然后,我将子项添加到 app.component.ts 文件中,类型为ElementRef,并在激活路由器出口时让它滚动到该文件。
export class AppComponent {
@ViewChild('topScrollAnchor') topScroll: ElementRef;
onNavigate(event): any {
this.topScroll.nativeElement.scrollIntoView({ behavior: 'smooth' });
}
}
Run Code Online (Sandbox Code Playgroud)
这是stackblitz中的代码
@ViewChild('topScroll') topScroll: ElementRef;
ngAfterViewInit()
{
interval(1000).pipe(
switchMap(() => of(this.topScroll)),
filter(response => response instanceof ElementRef),
take(1))
.subscribe((input: ElementRef) => {
input.nativeElement.scrollTop = 0;
});
}
Run Code Online (Sandbox Code Playgroud)
这对我来说就像一个魅力。如果你严格想遵循角度方式。
| 归档时间: |
|
| 查看次数: |
78771 次 |
| 最近记录: |