电梯组件

📌 电梯组件介绍
在日常开发中, 尤其是页面内容较长、包含多个区域的场景下(如商品菜单页、商品详情页、表单导航等), 我们常常需要实现一种 的能力,
方便用户快速跳转到页面的各个部分, 并且通过滚动时自动高亮当前的导航项目、,提升用户体验
这里介绍一个自研 的实现思路和效果. 它实现了:
-
📍 锚点定位跳转:点击导航项,页面平滑滚动至对应内容区域;
-
🔄 滚动联动高亮:滚动页面时,自动更新当前所在的导航项;
-
⚙️ 可配置导航项与内容结构:支持任意自定义导航项与对应区域;
-
🎯 支持嵌套布局与吸顶导航:适用于复杂布局中的滚动容器。
📐 前置知识:理解滚动相关的 DOM 属性
在构建 时,我们需要用到一些与滚动布局密切相关的 DOM 属性。下面简单介绍几个核心 API 的作用和差异:
属性名 | 含义 |
---|---|
可视区域高度,不包括滚动条或 border 部分 | |
整个内容高度(包括溢出隐藏部分)。内容超出可视区域的部分也会算进来。 | |
滚动的距离,即当前滚动条从顶部滚动了多少像素 | |
元素距父容器顶端的距离 |
rect 是一个包含以下属性的对象:
属性名 | 含义 |
---|---|
元素顶部到视口顶部的距离 | |
元素左边到视口左边的距离 | |
元素底部到视口顶部的距离 | |
元素右边到视口左边的距离 | |
元素自身的宽度 | |
元素自身的高度 |
✅ vs 对比
属性 | 含义 | 使用场景 | 单位 | 示例值 | 说明 |
---|---|---|---|---|---|
某个可滚动容器已滚动的垂直距离 | 判断滚动条滚了多少,触发吸顶等 | 120 | 容器向下滚动了 120 像素 | ||
当前元素相对于定位父元素(offsetParent)顶部的偏移 | 计算锚点元素的真实位置(绝对位置) | 300 | 元素在页面中离顶部 300 像素 |
❗ 常见误区
只有 能滚动的元素 才能用 否则它 始终是
🧠 实现原理解析
- 布局结构
组件分为两部分:
-
左侧菜单(导航):点击菜单项可以跳转到对应的内容区域。
-
右侧滚动内容区域:展示每个区块内容,监听其滚动位置变化与左侧导航联动。
- 锚点跳转机制
点击左侧导航时:
- 获取目标内容块的
- 根据 (头部高度偏移量)计算精确滚动目标
- 使用 平滑滚动到目标位置
- 关闭滚动监听, 等滚动结束后再重新开启监听(防止跳转时, 菜单目录跟着联动跳转)
- 滚动联动机制
滚动内容区域时:
- 节流触发 避免性能问题
- 获取滚动容器的 判断当前滚动位置
- 将当前滚动位置与所有内容块位置进行比对,得出当前处于哪个区块,并设置为激活项 特殊处理:
- 如果已经滚动到底部 则直接激活最后一个区块
🚧 待完善功能(To-Do)
- 吸顶导航支持: 实现右侧滚动内容区块的标题吸顶效果,提升阅读体验(可配合 position: sticky 实现)。
- 滚动动画回弹优化: 当前 scrollTo 使用浏览器原生平滑滚动,后续可接入自定义滚动动画(如贝塞尔曲线)增强流畅度与控制。
- 支持动态内容高度变化: 当前楼层位置高度是初始化时计算的,若内容异步加载或动态变化,高度计算可能不准确,后续可考虑监听 DOM 变化(如 ResizeObserver)自动更新。