路由器锚点滚动不适用于材质的垫边导航容器[全屏]



RouterModule锚点滚动基于视口可滚动区域,因为mat-sidenav-container将自身设置为 100% 高度,当与fullscreen属性一起使用时,RouterModule不会更改视口溢出。

<mat-sidenav-container fullscreen>
<mat-sidenav-content></mat-sidenav-content>
</mat-sidenav-content>

在上面的示例中,所有可滚动内容都位于mat-sidenav-content中。

有没有办法让RouterModule使用mat-sidenav-container而不是视口作为滚动容器参考?

请参阅堆栈闪电战示例。 查看没有全屏的工作版本。

我遇到了完全相同的问题。 我通过以下方式解决了它:

  1. 对于垫侧导航容器,我没有设置"高度",而是将"最小高度"设置为 100%,以便可滚动元素是正文,而不是侧导航容器,但如果内容小于视口,容器仍将拉伸以覆盖它。请记住,这可能会影响您的布局,具体取决于您的实现,但这对于此解决方案的工作绝对是必不可少的。
  2. 垫子
  3. 工具栏的高度(在垫子边导航容器上方(是 64px,我为正在滚动的元素保留的边距是 16px,因此 (64 + 16( 是 y 偏移量
  4. 在 app.module.ts 中,NgModule 的内部导入
RouterModule.forRoot(
routes,
{
anchorScrolling: 'enabled',
scrollOffset: [0, 64 + 16]
}),
  1. 假设 mat-sidenav-container 位于 app.component.html 中,我将以下内容添加到 ngOnInit(( 中的 app.component.ts 中。 (请记住采取预防措施,防止由于订阅而导致的内存泄漏,尽管这是应用程序组件,所以这并不重要(
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)
)));

其他改进:

  • 而不是硬编码 y 偏移量 - 可以查询 mat-toobar 的 clientHeight 和要滚动到的元素的 clientTop,并将它们相加以获得偏移量
  • 我只测试过滚动到作为垫边导航内容的直接后代的元素。也许这个逻辑可以扩展到适用于嵌套元素、嵌套路由等

有没有一个垫子边导航内容解决方案? 作为一种解决方法,我正在订阅路由器事件并查看 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( ... );
}
}
} );

最新更新