We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
产品有三宝,弹窗,浮层加引导; 设计有三宝,透明,阴影加圆角; 运营有三宝,短信,推送加红包; 程序员有一宝,这个做不了。
随着移动端市场的份额越大,需求就越多样化。我们今天讨论的是移动端的滚动穿透问题。上面这段调侃的话可以看出需求中弹窗浮层还是挺常见的,那这个和滚动穿透有什么联系呢?
我先解释下什么是滚动穿透:
页面滑出了一个弹窗,我们用手指触摸屏幕滑动时,会发现弹窗下面的内容还是在滚动。这个现象就是滚动穿透。
接下就说下我对滚动穿透问题解决方案探索的过程,希望对大家有点启发。
需求: 希望在点击图片的时候,从下方弹一个全屏的弹框来描述这张图片的详情。
接到这个需求觉得没有难度,很快就提测了,然后就开始逛逛掘金。可刚看大佬们的文章看的开心的时候,测试就在微信我。心想来 bug 了? 突然意识到写弹窗的时候忘记处理滚动穿透的问题了。记得第一次遇到这个问题的时候也是找了很久的资料。
找到的第一个方法就是当弹窗触发的时候,给 overflow: scroll: 的元素加上一个 class (一般都是 body 元素)。退出的时候去掉这个 class。下面为了方便,会直接用 body 元素来代指弹窗下方的元素。
overflow: scroll:
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。
scrollTop
这个新问题比起滚动穿透本身来说更加麻烦,所以这个方案是要进行优化的。
既然添加 modal_open 这个 class 会使 body 的滚动位置会丢失,那么我们为什么不在滚动位置丢失之前先保存下来,等到退出弹窗的前在將这个保存下来的滚动位置在设置回去。然后就朝着这个方向开始 coding 。
modal_open
// 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'; } }
方案二可以达到以下效果:
方案二可以适应绝大多数的弹窗需求,提测后测试方也没有在提其他问题,这个问题算是完美的解决了。不过我在这个过程有一个疑问:
IOS 自有的橡皮筋效果会导致页面会出现短暂卡顿现象,暂时没有找到原因,请教各位。
使用 preventDefault 阻止浏览器默认事件:
preventDefault
var modal = document.getElementById('modalBox'); modal.addEventListener('touchmove', function(e) { e.preventDefault(); }, false);
这个方案只适用于这个弹窗本身的高度小于屏幕的高度,即不可滚动的时候。touchmove 比 touchstart 更加合适。因为 touchstart 会连点击事件都阻止。
touchmove
touchstart
使用插件:
对于插件我的态度是,除非是自己实现起来太复杂,否则还是自己花点时间去实现。原因有二:
以上。
如果你想进【大前端交流群】,关注公众号点击“交流加群”添加机器人自动拉你入群。关注我第一时间接收最新干货。
The text was updated successfully, but these errors were encountered:
No branches or pull requests
背景
随着移动端市场的份额越大,需求就越多样化。我们今天讨论的是移动端的滚动穿透问题。上面这段调侃的话可以看出需求中弹窗浮层还是挺常见的,那这个和滚动穿透有什么联系呢?
我先解释下什么是滚动穿透:
接下就说下我对滚动穿透问题解决方案探索的过程,希望对大家有点启发。
需求
方案
接到这个需求觉得没有难度,很快就提测了,然后就开始逛逛掘金。可刚看大佬们的文章看的开心的时候,测试就在微信我。心想来 bug 了?
突然意识到写弹窗的时候忘记处理滚动穿透的问题了。记得第一次遇到这个问题的时候也是找了很久的资料。
方案一:
找到的第一个方法就是当弹窗触发的时候,给
overflow: scroll:
的元素加上一个class
(一般都是body
元素)。退出的时候去掉这个class
。下面为了方便,会直接用body
元素来代指弹窗下方的元素。上面的这个方法可以解决滚动穿透问题,却也会带来新的问题。
即:
这个新问题比起滚动穿透本身来说更加麻烦,所以这个方案是要进行优化的。
方案二:
既然添加
modal_open
这个class
会使body
的滚动位置会丢失,那么我们为什么不在滚动位置丢失之前先保存下来,等到退出弹窗的前在將这个保存下来的滚动位置在设置回去。然后就朝着这个方向开始 coding 。方案二可以达到以下效果:
body
是固定的无法滚动;body
的滚动位置不会丢失;body
有 scroll 事件;方案二可以适应绝大多数的弹窗需求,提测后测试方也没有在提其他问题,这个问题算是完美的解决了。不过我在这个过程有一个疑问:
其他方案:
使用
preventDefault
阻止浏览器默认事件:这个方案只适用于这个弹窗本身的高度小于屏幕的高度,即不可滚动的时候。
touchmove
比touchstart
更加合适。因为touchstart
会连点击事件都阻止。使用插件:
对于插件我的态度是,除非是自己实现起来太复杂,否则还是自己花点时间去实现。原因有二:
以上。
参考
最后
如果你想进【大前端交流群】,关注公众号点击“交流加群”添加机器人自动拉你入群。关注我第一时间接收最新干货。
The text was updated successfully, but these errors were encountered: