项目开发遇到一个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没有问题,更老的手机不在咱们的兼容范围内了。