web端及移动端及uniapp滑动穿透问题解决

困扰了我一周的问题,终于在日焦头烂额中有了结果,分享记录一下,留给有缘人

起因

在这里插入图片描述
无法展示实际业务代码,写了个demo,起因是因为需要在u-modal弹窗textarea中添加超出文本滑动显示的效果,当时用的是uview的组件,发现无论如何都无法滑动,后面查看源码才发现,所有的滑动事件都被u-popup阻止了,所以只能被迫修改源码,同时当时是一个uniapp项目,既要设配web端,也要适配h5端

web端滑动穿透

滑动穿透问题其实只是一个浏览器的机制,叫做滚动链,当容器滚动到边界时,再继续滚动时,会将这一事件向外冒泡,从而出现当容器滚动到底部,继续滚动,外层容易会被滚动的现象,web端解决方案有两个

  1. overflow:hidden,这里我特意看了element-ui及vant组件库的modal弹窗,发现他们都有一个lockscroll的属性,用于锁住底层body元素,其原理是在modal显示时给body添加overflow:hidden样式,在modal隐藏时动态删除或还原为overflow原始值,从而解决web端的滑动穿透问题,但是我们用的时uniapp,需要考虑小程序端,小程序端无法很轻易地操作dom,没有document,也没有body,因此这个方案在uniapp端并不适用
document.body.style = "overflow:hidden"
  1. overscroll-behavior-y,这是一个非常有用的属性,让你可以控制浏览器过度滚动时的表现——也就是滚动到边界。但同样的也有不足之处,就是他只对overflow为scroll的组件生效,就像上面那个案例,除了textarea输入框的区域,弹窗其他白色区域还是会造成滚动穿透,只有在内容铺满弹窗并且处于可滚动状态时,当前样式才会生效。
overscroll-behavior: auto; /* 默认 */
overscroll-behavior: contain;
overscroll-behavior: none;

综上所述,web端的最佳解决方案就是给body元素动态设置overflow:hidden属性。

uniapp滑动穿透

小程序端没有document,难以直接获取dom元素,即使能获取dom元素,也只能从dom中读取一些基础属性,无法动态去设置,这就导致在web端可以用的body设置overflow:hidden方案行不通,在苦思冥想两天后,发现了一个突破点

  1. page-meta,通过这个标签,我们可以给页面配置一些属性,包括但不限于page的样式,这意味着我们可以根据modal的状态动态给page标签添加overflow:hidden,从而实现与web端相类似的效果,以此解决滑动穿透问题,但这里也需要注意,page-meta只有为页面的第一个元素时才会生效,否则不生效
//页面首节点
<page-meta :page-style="visible?'overflow:hidden':''"></page-meta>

附page-meta官方文档:https://uniapp.dcloud.net.cn/component/page-meta.html

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐