RouterModule
锚点滚动基于视口可滚动区域,因为mat-sidenav-container
在与fullscreen
属性一起使用时将自身设置为100%高度,因此RouterModule
不会发生视口溢出而改变。
<mat-sidenav-container fullscreen>
<mat-sidenav-content></mat-sidenav-content>
</mat-sidenav-content>
mat-sidenav-content
内。
有没有办法让
RouterModule
使用mat-sidenav-container
代替视口作为滚动容器参考?
请参阅 StackBlitz 示例。 请参阅不带全屏的工作版本。
我遇到了完全相同的问题。 我解决了这个问题:
RouterModule.forRoot(
routes,
{
anchorScrolling: 'enabled',
scrollOffset: [0, 64 + 16]
}),
this.router.events
.pipe(
//take only scroll events that have an anchor specified
filter(e => e instanceof Scroll && !!e.anchor),
//wait for the DOM to resolve. It worked with 10, but it was a small test case
//so I used 100 just in case
delay(100),
//take the element that the anchor points to
map((e: Scroll) => document.getElementById(e.anchor)),
//ignore if no element was found
filter(el => !!el)
)
.subscribe(el =>
document.scrollingElement
.scroll(
0,
window.scrollY + el.getBoundingClientRect().top - (64 + 16)
)));
其他改进:
有一个 mat-sidenav-content 解决方案吗? 作为解决方法,我订阅路由器事件并查看 Scroll.anchor, 然后按照 在 Angular 6 中使用锚链接#id 我可以影响视图子项的平滑滚动...
例如。
在 html 中:
<a routerLink="/menu" fragment="pizza">Pizza</a>
...
<div #pizza>...</div>
在组件中:
@ViewChild( 'pizza' ) pizza: ElementRef
this.router.events.subscribe( (e:RouterEvent) => {
if ( e instanceof Scroll ) {
if ( e.anchor ==== 'pizza' ) {
this.pizza.nativeElement.scrollIntoView( ... );
}
}
} );
对于 app.component.html 中带有 mat-sidenav-container 的 Angular/Angular Material 16 应用程序,我可以通过将以下 css 添加到 AppComponent 来实现锚点滚动:
mat-sidenav-container, mat-sidenav-content {
overflow: unset;
}
您需要在自己的应用程序中进行测试,以确保这不会扰乱任何其他滚动行为。