前端词典 —— 滚动穿透

栏目: CSS · 发布时间: 5年前

内容简介:产品有三宝,弹窗,浮层加引导;设计有三宝,透明,阴影加圆角;运营有三宝,短信,推送加红包;

产品有三宝,弹窗,浮层加引导;

设计有三宝,透明,阴影加圆角;

运营有三宝,短信,推送加红包;

程序员有一宝,这个做不了。

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

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

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

接下就说下我对滚动穿透问题解决方案探索的过程,希望对大家有点启发。

需求

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

方案

接到这个需求觉得没有难度,很快就提测了,然后就开始逛逛掘金。可刚看大佬们的文章看的开心的时候,测试就在微信我。心想来 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 的滚动位置会丢失,也就是 bodyscrollTop 属性值会变为 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

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

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

其他方案:

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

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

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

使用插件:

对于插件我的态度是,除非是自己实现起来太复杂,否则还是自己花点时间去实现。原因有二:

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

以上。

参考

  1. developer.mozilla.org/en-US/docs/…
  2. uedsky.com/2016-06/mob…

前端词典系列

《前端词典系列》这个系列会持续更新,希望大家在阅读的过程当中可以斧正文中出现不严谨或是错误的地方,本人将不胜感激;若通过本系列而有所得,本人亦将不胜欣喜。

内容:前端以及网络相关知识点的介绍并加以实际应用作为辅助。

目的:这个系列的文章可以对读者起到一点帮助,解开一些迷惑。

希望各位多指点一二,不吝赐教。


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Pro Git (Second Edition)

Pro Git (Second Edition)

Scott Chacon、Ben Straub / Apress / 2014-11-9 / USD 59.99

Scott Chacon is a cofounder and the CIO of GitHub and is also the maintainer of the Git homepage ( git-scm.com ) . Scott has presented at dozens of conferences around the world on Git, GitHub and the ......一起来看看 《Pro Git (Second Edition)》 这本书的介绍吧!

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码

html转js在线工具
html转js在线工具

html转js在线工具