最近在开发的时候,碰到scrollview在弹出层滑动时,影响了页面的滚动,在网上找了很多种方法之后,在这里谈一谈我的理解:
解决方案一:弹出层没有需要滚动的容器时,可以直接给整个弹出层加@touchmove.stop.prevent事件阻止滑动穿透;
解决方案二:给页面最外层的view动态绑定,(没有搜索到可以给page直接动态绑定css属性的方法)
overflow:hidden; height:100vh;
相当于固定了页面的高度。使得页面没有滚动条,从而页面也就不会滚动了。但是这样的话,每一次动态给page绑定属性的时候,页面都会回弹到顶部,操作体验非常的不好。
解决方案三 给page添加属性:
overflow: visible; height:100vh;最外层元素加属性:
overflow::auto; height:100%;当拉起弹框时动态给最外层元素加属性
overflow:hidden;这种解决方案我理解为直接让最外层滚动,并没有触发页面级的滚动,看效果也解决了页面回弹的问题,但是美中不足的是,失去了页面级的滚动,如果页面需要监听滚动条的位置,那这种方案就没有办法用了;
所以为了符合我的需求,我最终使用的方法如下: 首先在页面弹框弹出时,动态给最外层元素加如下属性
position: fixed; top:0; left:0; overflow: hidden;通过小程序的onPagescroll事件,实时记录下当前滚动条距离页面顶部的距离
onPageScroll(e) { if(e.scrollTop>0){ this.nowscrolltop = e.scrollTop }else{ } this.topopacity = e.scrollTop / 300; },要判断是不是0,因为当设置最外层position:fixed的时候,滚动条会回弹到0,这时候不能赋值
最终再给最外层元素绑定属性:
:style="{'transform' : transformshow ? 'translateY('+(-nowscrolltop) +'px)' : 'none'}"就是在回弹到顶部之后,通过transform再让最外层view向下平移一段距离,这里使用transform而不直接用top的原因是因为用了top之后,我的弹框使用的animate属性就会变得特别卡。所以在弹出层的最外层,要给一个相反的transform
:style="{'transform' : transformshow ? 'translateY('+(nowscrolltop) +'px)' : 'none'}"关闭弹框的时要加入如下代码(如果你实验到这里,那肯定知道我这代码的意思,这就不过多解释了)自我感觉良好的解决方案诞生了~
this.transformshow=!this.transformshow this.$nextTick(()=>{ uni.pageScrollTo({ scrollTop: this.nowscrolltop, duration:0 }); })注意:弹框的外层的高度要给100vh