
之前面试腾讯时,技术面官指着简历上的项目简介,突然问了这么一句:
“你说项目中用了电梯导航,能说说你是怎么实现的吗?如果让它支持滚动高亮和点击跳转,还能兼顾性能,你怎么设计?”
我当时愣了一下。这个功能确实写过,逻辑也不复杂,但面试这种时候光说“用scroll监听 + offsetTop”肯定不够,于是我试着从交互细节、性能控制、边界判断等多个维度去分析,才算答得还算满意。
这篇文章,就来完整梳理下这个经典面试点——混动电梯导航的完整实现思路。
电梯导航,就是页面滚动联动导航条,常出现在文档、商品详情页、知乎目录等场景:
如果你只考虑其中一个方向,实现是很简单的。但大厂常常问的是:“混动联动怎么做?”
也就是说,点击跳转+滚动跟随两个方向都要顺滑切换,不能有“跳一下”、“闪一下”的体验问题。
这个问题其实不是为了考你 API,而是看你是否有整体思考能力:
如果你回答“我就用 scroll 事件 + offsetTop 判断”,那么……
👨💻 面试官内心 OS:你只知道怎么写代码,不知道怎么设计交互。
这里我们不看代码,只讲实现思维和面试答题结构,让你可以在短时间内说清楚:
思路很简单:我们给每个内容块一个“标记”(比如 id 或 ref),在初始化时计算它们的垂直位置。
为什么需要缓存?
因为滚动监听频率极高,不能每次都去 query DOM,影响性能。
注意:如果页面是动态高度(比如懒加载、图片加载),你要监听 resize 或加载完成后再重新计算。
当用户滚动页面时,我们要知道“现在在哪一块”。
怎么判断?
依次判断各个区域的 offsetTop,只要当前 scrollTop 超过了某个区域的位置,就认为进入了该区域。
有两个小细节:
用户点击导航项时,我们需要:
这个状态怎么用?
避免“你在点击滚动,我在监听 scroll 又触发高亮更新”出现冲突。
可以用 setTimeout 或监听滚动完成的回调(比如监听 scrollend),等滚动完成后再取消这个状态。
你如果直接监听 scroll,然后每次都更新高亮状态,会造成页面卡顿。
解决办法有两个:
lodash.throttle 或 requestAnimationFrame 来节流;电梯导航在移动端还得考虑:
window,而是某个 .scroll-view最后强调一句:
“这个需求看似简单,但如果不考虑用户体验和性能细节,很容易出现闪跳、卡顿、判断不准确等问题。”
面试官听到这句话,基本知道你是认真做过业务的选手。

电梯导航不仅是个交互组件,更是对你“事件监听、性能优化、状态控制、用户体验”等综合能力的考察。
会写不难,会讲才是面试加分项。