最近在做小程序项目的时候,因为一个弹窗滚动事件,造成了「页面穿透」。简单解释一下这个现象,就是底部页面是一个可以滚动的页面,有一个绝对定位为fixed的弹窗,这个弹窗内也是可以滚动的,然后在我们滚动弹窗的时候,发现弹窗内和底部内容都一起滚动,这显然不是我们想要的效果。效果如下图:
这是为啥呢?我们想要的效果应该是滚动弹窗的时候,不会影响外层的滚动,这就是「页面滚动穿透」了,我上网查了下,似乎。。。。这是微信小程序的BUG,是一个大坑。。。不过还是有一些解决方法的。
<!--index.wxml-->
<view class="outer-content">
outer contentouter contentouter contentouter contentouter contentouter contentouter contentouter content
<view class="inner-content">
inner-content inner-content inner-content inner-content inner-content inner-contentinner-content inner-content inner-contentinner-content inner-content inner-contentinner-content inner-content inner-content
inner-content inner-content inner-content inner-content inner-content inner-contentinner-content inner-content inner-contentinner-content inner-content inner-contentinner-content inner-content inner-content
inner-content inner-content inner-content inner-content inner-content inner-contentinner-content inner-content inner-contentinner-content inner-content inner-contentinner-content inner-content inner-content
</view>
</view>
同时我们也记录下在「微信开发者工具」上的效果。上拉弹出层的内容,只有在弹出层触底后,才会在底层页面进行滑动,并且不影响弹出层内滑动。
然后网上搜索总结了下解决方案:
方案一:增加「catchtouchmove」属性
这种情况下是在「inner」层增加一个「catchtouchmove」。不过增加后,在弹窗层滑动,发现弹窗层和底层页面都不能滑动,所以此方案适合:弹窗层不需要滑动的情况。
方案二:可以在弹出层出现的时候,给底层增加一个class,然后弹出层消失的时候去除这个class。
这个class的主要特点就是将底层设置了一个绝对定位fixed。但是这里有个bug,就是如果底层滑动了一部分,弹出层出现后,底层会跳回顶部。这个就很不友好了,因为我们想要的是弹出层出现,底部没有变化也不能滑动。
样式和效果图如下:
.tripList_root {
top:0px;
left: 0px;
width: 100%;
height: 100%;
overflow: hidden;
position: fixed;
z-index: 0;
}
「微信开发者工具」和真机上效果相同。
方案三:使用<scroll-view>标签
为了达到理想效果,后来发现「scroll-view」标签是可以实现的。同时记得加上「scroll-y」属性,就可以上下滑动了,效果如下。
不过在「微信开发者工具」上效果不同,在弹出层滑到顶部或者底部,再次滑动则会影响到底部页面。效果如下:
以上是我对小项目完成一个功能时的记录,但是同样引起了我的思考。
问题一:在弹出层添加属性「catchtouchmove」,明明是为了防止弹出层的「touchmove」冒泡影响到底层的滑动,而且弹出层的内容是超出显示区域的,为啥弹出层不能滑动了?
答:还是自己对「catchtouchmove」的认知不够全面,查询资料和对实际效果的认识之后,「catchtouchmove」应该不仅会阻止事件的冒泡,还会阻止事件的默认行为,相当于preventDefault.所以弹出层不能滑动了。
问题二:既然微信小程序有「页面滚动穿透」的坑,其他页面是不是也有呢?于是开始尝试手机端的web页面。