我现在正在遇到一模一样的问题。我通过以下方式解决了它:
- 对于mat-side-nav-container,我没有设置'height',而是设置'min-height'为100%,这样可滚动的元素就是body,而不是sidenav容器,但万一内容少与视口相比,容器仍会拉伸以覆盖它。请记住,这可能会影响您的布局,具体取决于您的实现,但这对于此解决方案的工作是绝对必要的。
- mat-toolbar 的高度(在 mat-sidenav-container 上方)是 64px,我为正在滚动的元素保留的边距是 16px,因此 (64 + 16) 是 y 偏移量
- 在 app.module.ts 中,NgModule 的内部导入
RouterModule.forRoot(
routes,
{
anchorScrolling: 'enabled',
scrollOffset: [0, 64 + 16]
}),
- 假设 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,然后添加它们以获得偏移
- 我只测试了它是否可以滚动到 mat-sidenav-content 的直接后代元素。也许这个逻辑可以扩展为适用于嵌套元素、嵌套路由等等等