用IntersectionObserver实现吸顶效果
用 IntersectionObserver 实现吸顶效果
开发中,需要实现一个二级工具菜单栏吸顶灯的效果
效果如下图 1,框选住的部分会在滚动的时候吸附顶部,在下滑的过程中,回到原来的位置时,又恢复 static 的效果,如图 2
思路
方案一 : position:sticky
本来第一个想到的时使用 css 的 position:sticky,达到吸附的效果,但是实践的时候发现,如果恢复到图 2 的状态,这个二级菜单元素层级会非常深,所以中间各层元素很难去控制 overflow 属性,而在 overflow:hidden 的时候,position:sticky 是无法生效的
方案二 : js 监听 scroll 事件
这里通过 js 监听 scroll 事件,然后判断元素距离顶部的偏移量,我这个场景下顶部一级菜单高度是 60px,所以如果二级菜单顶部距离页面整体可视区域<60px 的时候,修改二级菜单 position 为 fixed,相反>60px 的时候,则修改为 static ,让二级菜单回到文档流中。其中用到了 Dom 的 getBoundingClientRect 的方法,获得元素各个尺寸数据
代码如下:
1 |
|
但是这个方法也不够优雅 ,有三点理由,1. 滚动的时候会一直通过 getBoundingClientRect 去获取元素距离顶部的距离,导致页面不断重排,过重的渲染会影响整体性能。如果通过节流的方式对滚动函数做包装,则会导致页面无法准确抓取边界值,导致吸附反应迟钝,如下图所示
方案三 : IntersectionObserver
MDN:https://developer.mozilla.org/zh-CN/docs/Web/API/Intersection_Observer_API
IntersectionObserver 的作用是一个元素的相交检测,例如元素滚出/滚回页面可视区,这个就是我们想要的效果,赞 👍
接下来,修改原有的代码:
1 |
|
这里需要注意的两点是,关于 IntersectionObserver 第二个参数threshold
和rootMargin
的使用,代码中有注释申明
完成效果:
注意,虽然大部分浏览器都兼容了 IntersectionObserver,但是还有有些刺头没有这个 api ,所以需要自己考量一下是否写两套来适应没有 IntersectionObserver 的情况
各浏览器适配图
感谢阅读,勘误、纠错或其他请联系progerchai@gmail.com,或者点击这里提 issue 给我
欢迎交流 👏,你的每一次指导都可以让我进步
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!