龙空技术网

前端基础面试:什么是滚动穿透?有哪些解决滚动穿透问题的方法?

代码开发 571

前言:

现在咱们对“jquery滚动时间”大致比较讲究,各位老铁们都想要知道一些“jquery滚动时间”的相关知识。那么小编在网络上收集了一些有关“jquery滚动时间””的相关文章,希望姐妹们能喜欢,同学们一起来学习一下吧!

随着移动端市场的份额越大,需求就越多样化。今天讨论的是移动端的滚动穿透问题。需求中弹窗浮层还是挺常见的,那这个和滚动穿透有什么联系呢?

先解释下什么是滚动穿透:

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

需求

需求: 希望在点击图片的时候,从下方弹一个全屏的弹框来描述这张图片的详情。

方案

接到这个需求觉得没有难度,很快就提测了。突然意识到写弹窗的时候忘记处理滚动穿透的问题了。

方案一:

第一个方法就是当弹窗触发的时候,给 overflow: scroll的元素加上一个 class (一般都是 body 元素)。退出的时候去掉这个 class。为了方便,会直接用 body 元素来代指弹窗下方的元素。

// css 部分modal_open { position: fixed; height: 100%;}// js 部分document.body.classList.add('modal_open');document.body.classList.remove('modal_open');

上面的这个方法可以解决滚动穿透问题,却也会带来新的问题。

即:

body 的滚动位置会丢失,也就是body 的 scrollTop 属性值会变为 0。

这个新问题比起滚动穿透本身来说更加麻烦,所以这个方案是要进行优化的。

方案二:

既然添加 modal_open 这个 class 会使 body 的滚动位置会丢失,那么我们为什么不在滚动位置丢失之前先保存下来,等到退出弹窗的前在將这个保存下来的滚动位置在设置回去。

// css 部分.modal_open { position: fixed; height: 100%;}// js 部分/** * ModalHelper helpers resolve the modal scrolling issue on mobile devices *  */var ModalHelper = (function(bodyClass) { var scrollTop; return { afterOpen: function() { scrollTop = document.scrollingElement.scrollTop || document.documentElement.scrollTop ||  document.body.scrollTop; document.body.classList.add(bodyClass); document.body.style.top = -scrollTop + 'px'; }, beforeClose: function() { document.body.classList.remove(bodyClass); document.scrollingElement.scrollTop = document.documentElement.scrollTop = document.body.scrollTop = scrollTop; } };})('modal_open');// methodmodalSwitch: function(){ let self = this; if( self.switchFlag === 'close' ){ ModalHelper.afterOpen(); self.switchFlag = 'open'; }else{ ModalHelper.beforeClose(); self.switchFlag = 'close'; }}

jQuery:

方案二可以达到以下效果:

弹窗滚动的时候,下方的 body 是固定的无法滚动;body 的滚动位置不会丢失;body 有 scroll 事件;

方案二可以适应绝大多数的弹窗需求,提测后测试方也没有在提其他问题,这个问题算是完美的解决了。不过有一个疑问:

IOS 自有的橡皮筋效果会导致页面会出现短暂卡顿现象,暂时没有找到原因,请教各位。

其他方案:

使用 preventDefault 阻止浏览器默认事件:

var modal = document.getElementById('modalBox');modal.addEventListener('touchmove', function(e) { e.preventDefault();}, false);

这个方案只适用于这个弹窗本身的高度小于屏幕的高度,即不可滚动的时候。touchmove 比 touchstart 更加合适。因为 touchstart 会连点击事件都阻止。

使用插件:

除非是自己实现起来太复杂,否则还是自己花点时间去实现。

原因有二:

使用插件就意味着需要引入的文件至少多了一个。插件过多,担心日后项目升级维护成本加大。

标签: #jquery滚动时间