angular - 路由器 anchorScrolling 不适用于 Material 的 mat-sidenav-container [全屏]
问题描述
锚滚动基于RouterModule
视口可滚动区域,mat-sidenav-container
当与属性一起使用时将 ifself 设置为 100% 高度fullscreen
,没有视口溢出RouterModule
可更改。
<mat-sidenav-container fullscreen>
<mat-sidenav-content></mat-sidenav-content>
</mat-sidenav-content>
在上面的示例中,所有可滚动内容都存在于mat-sidenav-content
.
有没有办法代替视口作为滚动容器参考RouterModule
?mat-sidenav-container
请参阅StackBlitz 示例。查看没有全屏的工作版本。
解决方案
我现在正在遇到一模一样的问题。我通过以下方式解决了它:
- 对于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 的直接后代元素。也许这个逻辑可以扩展为适用于嵌套元素、嵌套路由等等等
推荐阅读
- java - 在 Spring Boot 项目中声明同一类/DAO 的多个实例是否有害?
- angular - 如何从Angular http post返回OKObjectResult作为字符串
- reactjs - 使用 Apollo react 用于 S3 图像上传的 useMutation 加载器
- machine-learning - 非凸优化
- css - 如何从左到右逐渐改变元素的背景颜色
- java - 有没有办法验证正则表达式在 Java 中完全匹配?
- python - Keras:keras 模型的二阶导数始终为 0
- angular - 无法在页面加载时将值设置回角度选择下拉列表
- conda - 如何将非代码文件添加到 conda 包?
- javascript - 带有虚拟填充的猫鼬自定义模式/类型适用于 Model.populate 但不适用于 Document.populate