我正在使用 angular 5。我有一个仪表板,其中很少有内容很小的部分和很少有内容很大的部分,以至于我在进入顶部时更改路由器时遇到了问题。每次我需要滚动到顶部。谁能帮我解决这个问题,这样当我更换路由器时,我的视图始终保持在顶部。
提前致谢。
我正在使用 angular 5。我有一个仪表板,其中很少有内容很小的部分和很少有内容很大的部分,以至于我在进入顶部时更改路由器时遇到了问题。每次我需要滚动到顶部。谁能帮我解决这个问题,这样当我更换路由器时,我的视图始终保持在顶部。
提前致谢。
有一些解决方案,请确保全部检查:)
路由器sockets将activate
在实例化新组件时发出事件,因此我们可以使用(activate)
滚动(例如)到顶部:
应用程序组件.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' }
在急切加载的module上使用,它将应用于所有路由:
RouterModule.forRoot(appRoutes, { scrollPositionRestoration: 'enabled' })
它也将进行平滑滚动,已经。然而,这对于在每个路由上都执行它有不便之处。
另一种解决方案是在路由器动画上进行顶部滚动。在要滚动到顶部的每个过渡中添加此内容:
query(':enter, :leave', style({ position: 'fixed' }), { optional: true })
如果你在 Angular 6 中遇到这个问题,你可以通过将参数添加scrollPositionRestoration: 'enabled'
到 app-routing.module.ts 的 RouterModule来解决它:
@NgModule({
imports: [RouterModule.forRoot(routes,{
scrollPositionRestoration: 'enabled'
})],
exports: [RouterModule]
})
编辑:对于 Angular 6+,请使用 Nimesh Nishara Indimagedara 的回答提到:
RouterModule.forRoot(routes, {
scrollPositionRestoration: 'enabled'
});
原答案:
如果一切都失败了,那么在模板(或父模板)上使用 id="top" 在顶部(或所需的滚动到位置)创建一些空的 HTML 元素(例如:div):
<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
选项。
对于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'
}
人们可以使用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]));
}