直奔主题,这两天我负责开发的app内容遇到了一个问题:弹框底层页面还是能滑动问题(在Android和ios12系统一下是正常的,ios高版本可滑动)也就是我们所说的滑动穿透事件
我遇到的两种情况:
第一种:如图(当弹框中内容不需要滑动)
遇到这种情况网上一顿找,看看是什么原因造成的。说简单点就是滑动穿透事件造成
滑动穿透事件:有一层遮罩蒙层覆盖在body上时,当我们滚动遮罩层,它下面的内容也会跟着一起滚动,看起来好像是上面的滚动事件穿透到下面的DOM元素上一样,我们称之为滚动穿透。
解决办法网上有几种:(个人知道的三种:position:fixed方法、禁止滚动事件方法、引入iscroll.js方法)
一、position:fixed方法(我并没有用这种方法,原因:
1:我开发的是成熟的app避免改动过大、涉及到改动的都要再测试一遍,麻烦。
2:移动端不引入其他库的情况下处理的。其实在移动端写弹窗,内部滑动问题通过overflow:scroll解决不完美,安卓ios总之是会有一些问题的。)
1.当出现弹窗的时候,给body设置为 position:fixed;overflow:hidden;
2.关闭弹窗的时候,给body的这两个属性去掉。
注:这个时候你会发现每次关闭弹窗之后,总是在页面的最顶部。
因为出现弹窗的时候,整个body都脱离文档流了,所以关闭的时候肯定是以当前手机的最顶部为基准的 ,
我是这样解决的:每次点击弹窗按钮的时候,都会记录一下当前滑动的距离,然后当关闭弹窗的时候,再回到那个位置去,代码如下:
二、禁止滚动事件方法
1.利用禁止滚动:e.preventDefault()
2.用if判断是否阻止滚动事件
//弹框显示/隐藏 底部页面滑动
//passive 参数来兼容各个浏览器(ios12系统 默认true)
var canScroll = false;
document.addEventListener('touchmove',function(e){
if(canScroll){
e.preventDefault();
}
},{passive: false})
上述是我的解方法代码,代码中addEventListener的第三个参数共有三个、分别是capture: false、passive: false、once: false。三个属性都是布尔类型的开关,默认值都为 false
capture:capture 属性等价于以前的 useCapture 参数。
once:once 属性就是表明该监听器是一次性的,执行一次后就被自动 removeEventListener 掉,还没有浏览器实现它。
passive:如果我们是为了阻止页面滚动添加了上述代码,默认行为就是滚动页面,但是如果我们阻止了这一默认行为,浏览器是无法预先知道的,必须等待事件监听器执行完成后,才知道要去阻止默认行为。等待监听器的执行是耗时的,,有些甚至耗时很明显,这样就会导致页面卡顿。即便监听器是个空函数,也会产生一定的卡顿,毕竟空函数的执行也会耗时。所以就有了passive属性,如果要阻止默认事件可以设置passive:false
到此我面临的第一种问题已经解决!
然而几天后开发中有遇到一样的问题滑动穿透事件,到此我解决过一次以为能分分钟解决,下面我们接着说第二种问题。
第二种:如图(当弹框中内容需要滑动)
针对这个弹框我毅然决然的将上次的解决代码放上去。结果在测试时发现弹框底部页面不能滑动了就连弹框里面的内容也不能滑动了,弹框里面再弹弹框内容也不能滑动了!!!!
采用这种方案带来的最大的问题是:
所有的滚动事件全部被禁止了!
假如我们的浮层上真的需要滚动事件,就不能阻止这些元素的默认行为。
滑动穿透解决方法只能用在弹框里面内容不滑动情况使用。
解决办法:那就用第三种iscroll.js方法
三、iscroll.js方法
1.Scroll是一个类,每个需要使用滚动功能的区域均要进行初始化。每个页面上的iScroll实例数目在设备的CPU和内存能承受的范围内是没有限制的。尽可能保持DOM结构的简洁。iScroll使用硬件合成层但是有一个限制硬件可以处理的元素。
<div id="wrapper">
<ul>
<li>...</li>
<li>...</li>
...
</ul>
</div>
iScroll作用于滚动区域的外层。在上面的例子中,UL元素能进行滚动。只有容器元素的第一个子元素能进行滚动,其他子元素完全被忽略。
iscroll.js的初始化方式:
<script type="text/javascript">
var myScroll = new IScroll('#wrapper'); //初始化
</script>
iscroll.js的销毁方式:
myScroll.destroy();
myScroll = null;
说起用这个方法那是一个悲伤份故事,推荐大神博文一篇,必能不会让各路大佬失望。具体的方法和设置参数都介绍到了。我不多扯了。https://blog.csdn.net/amyloverice/article/details/79383712
滑动穿透是解决了,又出现一个问题:当app页面弹出弹框时有的时候是滑动正常有的时候回影响app的下拉刷新功能。故此有舍弃了此方法。
再次也介绍一位大佬博文:http://www.cnblogs.com/gaohui/p/5819777.html
最后用一个简单的方法解决了,到现在没有测试出什么问题
$('.cue-bg').on('touchmove',function(e) {
e.preventDefault();
})
$('.cue-bg')是弹框的遮罩层。
以上方法只是解决单一问题。在app中将弹框滑动穿透事件封装成函数还在进一步学习中... 各位大佬请指正帮忙!感谢