摘要:接下就说下我对滚动穿透问题解决方案探索的过程,希望对大家有点启发。心想来了突然意识到写弹窗的时候忘记处理滚动穿透的问题了。下期预告前端词典继承必懂知识点传送门前端词典代理的概念及其应用前端词典滚动穿透问题的解决方案
背景
产品有三宝,弹窗,浮层加引导;
设计有三宝,透明,阴影加圆角;
运营有三宝,短信,推送加红包;
程序员有一宝,这个做不了。
随着移动端市场的份额越大,需求就越多样化。我们今天讨论的是移动端的滚动穿透问题。上面这段调侃的话可以看出需求中弹窗浮层还是挺常见的,那这个和滚动穿透有什么联系呢?
我先解释下什么是滚动穿透:
页面滑出了一个弹窗,我们用手指触摸屏幕滑动时,会发现弹窗下面的内容还是在滚动。这个现象就是滚动穿透。
接下就说下我对滚动穿透问题解决方案探索的过程,希望对大家有点启发。
需求需求: 希望在点击图片的时候,从下方弹一个全屏的弹框来描述这张图片的详情。方案
接到这个需求觉得没有难度,很快就提测了,然后就开始逛逛掘金。可刚看大佬们的文章看的开心的时候,测试就在微信我。心想来 bug 了?
突然意识到写弹窗的时候忘记处理滚动穿透的问题了。记得第一次遇到这个问题的时候也是找了很久的资料。
找到的第一个方法就是当弹窗触发的时候,给 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 的滚动位置会丢失,那么我们为什么不在滚动位置丢失之前先保存下来,等到退出弹窗的前在將这个保存下来的滚动位置在设置回去。然后就朝着这个方向开始 coding 。
// css 部分 .modal_open { position: fixed; height: 100%; } // js 部分 /** * ModalHelper helpers resolve the modal scrolling issue on mobile devices * https://github.com/twbs/bootstrap/issues/15852 */ 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"); // method modalSwitch: function(){ let self = this; if( self.switchFlag === "close" ){ ModalHelper.afterOpen(); self.switchFlag = "open"; }else{ ModalHelper.beforeClose(); self.switchFlag = "close"; } }
方案二可以达到以下效果:
弹窗滚动的时候,下方的 body 是固定的无法滚动;
body 的滚动位置不会丢失;
body 有 scroll 事件;
方案二可以适应绝大多数的弹窗需求,提测后测试方也没有在提其他问题,这个问题算是完美的解决了。不过我在这个过程有一个疑问:
IOS 自有的橡皮筋效果会导致页面会出现短暂卡顿现象,暂时没有找到原因,请教各位。其他方案:
使用 preventDefault 阻止浏览器默认事件:
var modal = document.getElementById("modalBox"); modal.addEventListener("touchmove", function(e) { e.preventDefault(); }, false);
这个方案只适用于这个弹窗本身的高度小于屏幕的高度,即不可滚动的时候。touchmove 比 touchstart 更加合适。因为 touchstart 会连点击事件都阻止。
使用插件:
对于插件我的态度是,除非是自己实现起来太复杂,否则还是自己花点时间去实现。原因有二:
使用插件就意味着需要引入的文件至少多了一个。
插件过多,担心日后项目升级维护成本加大。
以上。
参考https://developer.mozilla.org/en-US/docs/Web/API/document/scrollingElement
https://uedsky.com/2016-06/mobile-modal-scroll/
前端词典系列《前端词典》这个系列会持续更新,每一期我都会讲一个出现频率较高的知识点。希望大家在阅读的过程当中可以斧正文中出现不严谨或是错误的地方,本人将不胜感激;若通过本系列而有所得,本人亦将不胜欣喜。
内容: 前端以及网络相关知识点的介绍并加以实际应用作为辅助。
目的: 这个系列的文章可以对读者起到一点帮助,解开一些迷惑。
希望各位多指点一二,不吝赐教。
下期预告【前端词典】继承 - JavaScript 必懂知识点
传送门【前端词典】代理的概念及其应用
【前端词典】滚动穿透问题的解决方案
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/117201.html
摘要:接下就说下我对滚动穿透问题解决方案探索的过程,希望对大家有点启发。心想来了突然意识到写弹窗的时候忘记处理滚动穿透的问题了。下期预告前端词典继承必懂知识点传送门前端词典代理的概念及其应用前端词典滚动穿透问题的解决方案 背景 产品有三宝,弹窗,浮层加引导; 设计有三宝,透明,阴影加圆角; 运营有三宝,短信,推送加红包; 程序员有一宝,这个做不了。 随着移动端市场的份额越大,需求就越多...
摘要:用于获得当前元素到定位父级顶部的距离偏移值。后来在项目中总会遇到滚动吸顶的效果需要实现,现在我将我知道的种滚动吸顶实现方式做详细介绍。有兼容性问题,在微信浏览器某些版本中的值会为,于是乎也就有了第三种方案的兼容性写法。修改版预览 这篇文章是三天前写就的,有大佬给我提了一些修改意见,我觉得这个意见确实中肯。所以就有了这个升级的修改版本。代码同步更新到 GitHub 了。 修改内容如下: 添加...
摘要:第一篇文章我会结合和的部分源码,来说明注入生命周期的过程。说到源码,其实没有想象的那么难。但是源码的调用树会复杂很多。应用的业务代码逐渐复杂,事件事件总线等通信的方式的弊端就会愈发明显。状态管理是组件解耦的重要手段。前言 这篇文章是【前端词典】系列文章的第 13 篇文章,接下的 9 篇我会围绕着 Vue 展开,希望这 9 篇文章可以使大家加深对 Vue 的了解。当然这些文章的前提是默认你对 ...
摘要:于是带着以下两个问题开始学习正向代理以及反向代理。客户端才能使用正向代理。传送门前端词典代理的概念及其应用前端词典滚动穿透问题的解决方案 前言 在平时的工作中,总是会遇到代理的概念。之前我只知道有代理这个概念,不过对其没有一个清晰的理解。于是带着以下两个问题开始学习正向代理以及反向代理。 什么是正向代理,什么是反向代理 正向代理可以做什么,反向代理可以做什么 概念 首先附上一张说明...
摘要:于是带着以下两个问题开始学习正向代理以及反向代理。客户端才能使用正向代理。传送门前端词典代理的概念及其应用前端词典滚动穿透问题的解决方案 前言 在平时的工作中,总是会遇到代理的概念。之前我只知道有代理这个概念,不过对其没有一个清晰的理解。于是带着以下两个问题开始学习正向代理以及反向代理。 什么是正向代理,什么是反向代理 正向代理可以做什么,反向代理可以做什么 概念 首先附上一张说明...
阅读 3427·2021-11-12 10:36
阅读 2733·2021-11-11 16:55
阅读 2957·2021-09-27 13:36
阅读 1613·2021-08-05 10:01
阅读 3554·2019-08-30 15:55
阅读 765·2019-08-30 13:01
阅读 1905·2019-08-29 17:16
阅读 2376·2019-08-29 16:40