弹层蒙版(mask),ios滚动穿透,咱们项目的解决方案

问题描述

项目开发遇到一个ios独有的问题,在wkwebview中稳定复现node

问题: 弹出一个蒙版,当在蒙版上面滑动的时候蒙版后面的内容滚动了android

这固然是ios的bug,可是通过咱们测试iphone7也会复现这个问题,因此没办法须要兼容。ios

百度了下好多思路web

方法1: 直接禁用滚动容器的overflow,而后记录scrollTop并恢复,这种方法不适合咱们当前场景。iphone

1. 浮层的入口有多个页面
2. 浮层后面可滚动的容器有多个(3个)
3. 滚动容器有横向和纵向滚动,很难记录scrollTop和scrollLeft

方法2: 禁用touchmove事件,一样会致使弹层容器没法滚动,很不幸咱们的弹层须要可以滚动。
方法3: 基于方法2,滚动容器使用better-scroll来滚动,这个基本能够解决问题,可是有better-scroll的主要问题,任何修改了layout都须要手动调用refresh不利于维护。函数

咱们的方法

一样基于方法2,咱们执行如下2步测试

1. 浮层容器对touchmove禁用
2. 滚动容器对touchmove阻止其冒泡,
    判断当前是否能够滚动(scrollHeight>offsetHeight),
    当能够滚动的时候不会触发滚动穿透,所以
    1. 能够滚动:不由用touchmove
    2. 不能滚动:禁用touchmove

代码:code

// touchmoveFix.js
// ios滚动穿透问题解决指令
const touchFix = {
  bind: function (el, binding, vnode) {
    el.addEventListener('touchmove', (e) => {
      // 滚动容器阻止冒泡,所以是否prevent由当前函数决定
      e.stopPropagation();
      let scrollEl = e.currentTarget;
      // 断定当前滚动容器是否能够滚动
      if(scrollEl.scrollHeight <= scrollEl.offsetHeight) {
        // 不能滚动的时候依然须要阻止滚动穿透
        e.preventDefault();
      }
    }, false);
  }
};

// 使用指令
<!-- 弹层阻止touchmove -->
<section class="popup" @touchmove.prevent>
    ...
    <div class="content" v-touch-fix>...</div>
    ...
</section>

// js引入
import touchFix from './touchmoveFix';

export default {
  ...
  directives: {
    touchFix
  },
  ...
};

是否完美

能够看到思路并不复杂,无非是滚动子元素来决定是否禁用touchmove事件。
可是此方案并不完美,由于当弹出层有表单元素时,弹出键盘后表单自己通常须要能够滚动,此时滚动的是body元素,当touchmove禁用后body是没法滚动的,暂无解法只能暂时用方法1事件

总结:

此方案适用于弹层中有滚动容器,不适用于弹层自己为1个表单ip

经测试:iphone5s和android没有问题,更老的手机不在咱们的兼容范围内了。

相关文章
相关标签/搜索