弹窗滚动穿透原理与解决方案的探讨

2,659 阅读2分钟
原创不易,如需转载请【联系作者】或【署名作者并注明文章出处】

是什么

先解释下什么是滚动穿透

页面滑出了一个弹窗,我们用手指触摸屏幕滑动时,会发现弹窗下面的内容还是在滚动。这个现象就是滚动穿透。

为什么

为什么会有这个现象呢

原因:使用系统的滚动,html和body的高度超出窗口的高度,自动使用系统滚动,这个滚动会导致滚动穿透。如下图,最顶上是视窗的高度,最底下是body的高度

MDN上这样解释这个问题

怎么办

1、body height 100% + 区域内滚动

  1. 在body下的div上使用自己的height:100%; overflow: auto/scoll;(在IOS上不流畅需要加 :-webkit-overflow-scrolling: touch;)
  2. .给html,body 增加{position:fixed;with100%;height:100%; } 使html,body不会再使用系统滚动;
  3. 发现在安卓手机上完美实现,但是IOS的滚动机制让使人头大,依然可以穿透,这时我们在弹窗后需要把滚动的div上加上 overflow:hidden; 去掉 -webkit-overflow-scrolling: touch; 属性在关闭弹窗的时候恢复为 overflow: auto; 再加上-webkit-overflow-scrolling: touch; 可以实现IOS的兼容;至此滚动穿透就被解决了。

2、touchmove + preventDefault

touchmove + preventDefault
打开模态框时,阻止touchmove
缺陷: 模态框内的滚动内容失去滚动效果。

3、标记位置,弹性容器

1、模态框打开前记录背景的移动位置,关闭后回弹回去

2、为模态框动态绑定区域内滚动样式

缺点:无法处理模态框透明时候的场景

4、锁定容器,内容偏移

模态框打开后,在背景层监听容器滚动事件,时刻触发回弹

demo发现,回弹会触发闪屏,考虑定位与优化

闪屏分析

分析每一次滚动间隔是否大于一帧时长

结果如图

结合刷帧策略,判断是scroll事件触发的时候触碰了刷帧的反向回弹

考虑是每一帧做一次回弹定位校准, 考虑使用requestAnimationFrame

LAST:

欢迎大家扫码关注我的公众号,你的关注就是我的动力。

原创不易,如需转载请【联系作者】或【署名作者并注明文章出处】