乐趣区

关于前端:iOS容器内嵌H5禁用整体弹簧效果

背景

iOS 内嵌 H5 页面有一个默认的弹簧成果,即整个页面能够被高低拖拽滚动
弹簧成果视频
但并非所有场景都心愿有这个成果的,本篇次要用于记录如何使其被禁用

正统做法

这种解决 WebView 容器默认成果最正统的形式,当然是让容器本人来提供 Bridge 开关,互联网 Hybrid 利用碰到相似问题通常也都是这么解决的。不过很惋惜咱们这边并没有 Native 开发,Bridge SDK 也不反对任何自定义扩大,所以只能用 H5 范畴内的野路子来解决了

禁用滚动

这个问题网上一搜其实有不少人都贴了本人的代码,思路都是通过禁用超出边界的滚动来实现的,不过我沾了几个伙计的代码后发现并不好使,要不就是压根不失效,要不就是页面外部本来能够高低滑动的区域也动不了了,毕竟好使的话我也犯不着写一篇网上一艘就有的解决方案了
网上代码不好使,但我也懒得本人写,虽说这个实现的大思路是比拟明确的,但要写的话思考的货色也不少,费神费劲费时间。那有没有适合的库曾经做过这个事了呢?

GitHub 援救世界

不晓得是哪里应用的不对,github 上有的库用起来也有问题,费了半天劲总算我找到了一个好使的 https://github.com/lazd/iNoBo…,这个库反对 script 标签引入,老我的项目也能用
具体应用形式如下:

  1. 尽早引入 inobounce.min.js,之后 window 上就会挂载 iNoBounce 属性
  2. 在一个适合的机会调用 window.iNoBounce.enable(),这个机会是指页面曾经齐全渲染进去,但单纯在跟页面的 mounted 应用发现有一些问题,会让页面整体错位,我在 mounted 里又提早了 500 毫秒后才失常,最终代码为

    // App.vue
    mounted () {setTimeout(() => {
       // 如果是 iOS, 则禁用弹簧成果
       this.disableBounce();}, 500);
    },
    
    disableBounce () {if (isIOS() && window.iNoBounce) {window.iNoBounce.enable();
     }
    }

    这么一搞 iOS 内嵌 H5 就悦目多了,整体感官和安卓就对立起来,少了页面的轻薄感。但事件到这里还没有完结

起初发现的问题

这个禁用弹簧性能上线后,咱们的异样监控陆陆续续收到一些 JS 报错信息

// 错误信息
TypeError: Argument 1 ('element') to Window.getComputedStyle must be an instance of Element

getComputedStyle 办法的入参有问题,在排查后发现是这个库里报进去的,inobounce.min.js 格式化后的具体位置如下

能够看到这个 el 的起源是事件入参 event 的 target 属性,这个玩意广泛认知上也不应该呈现空或者非 Element 对象,咱们的测试机也没能本地复现这个问题,狐疑可能是一些特定机型或场景才会呈现
尽管没有搞清楚 el 到底还能是什么,不过解决方案倒是非常简单,减少健壮性逻辑即可,将 while 那一行的条件批改后就没有再统计到 JS 异样了

el !== document.body && el !== document && el && el.nodeType === 1
退出移动版