ios下拉和上滑会出现白边, android下拉会出现白边,部分浏览器出现下拉刷新问题(chrome,360浏览器)
下面主要整理了下解决此问题测试用过的方案及存在的问题:
方案一:
document
passive选项用于优化scroll和touch事件,避免页面卡顿现象,默认false,为true时表示不阻止默认事件,如果此时回调函数有 e.preventDefault,浏览器则会报错:
优化原理:(以touchmove为例),页面不监听touchmove会正常滚动,一旦添加,浏览器便开始执行监听器,执行完之后才使页面滚动,如果执行监听器时间稍长就会造成滚动失效也就是页面卡顿,因为浏览器不知道到底要不要阻止默认事件(有没有添加preventDefault),等执行完监听器才知道结果,如果可以提前告诉浏览器要阻止默认行为就可以,passive便诞生了,在监听scroll和touch时,设置{passive: true}, 浏览器同时执行js和touchmove的默认行为,不会使页面卡顿,达到优化的效果。
而如果要阻止touchmove的默认行为,添加{passive: false},表示先不执行默认事件等执行回调时再看要不要阻止,遇到e.preventDefalut()彻底禁掉滚动。
默认为false,如果不写会怎样:经测试失效,因为某些浏览器做过优化,设为true了,比如: Safari 11.1
Updated root document touch event listeners to use passive mode improving scrolling performance and reducing crashes.
更新根元素(document)监听touch事件设置passive: true提高滚动性能减少卡顿,也就是说在监听document的touch事件时默认不阻止默认行为
对passive更充分的解释:passive 的事件监听器
此方案存在的问题:阻止了页面内所有的滚动事件
解决:判断e.target是否为页面可滚动元素,如果不是再阻止
方案二:
body
固定定位的元素不会随着页面滚动,因此body高度不能超过页面可视高度,否则不可见,可以在内容包一层,设定宽高为视口宽高,然后overflow:scroll
此方案存在的问题:
1、ios正常,安卓微信不可用,但浏览器正常[冒汗]
2、如果涉及到横竖屏切换,因为要拿到视口宽高,那就有的好好聊聊了
1.1 body直接使用 width: 100vw; height: 100vh; overflow: hidden 万事大吉,但还是存在一定的风险
1.2、如果通过js去获取宽高给body,问题就来了,横竖屏拿到的宽高在设备上表现不一致:
- 设备不同表现不同,获取姿势不对表现不同,屏幕转动后,部分浏览器获取到视口高度为转动之前的高度 【竖屏>横屏(此时拿到的是竖屏的高)>竖屏(此时拿到的是横屏的高)】
> screen.height 屏幕分辨率高度: 包含浏览器地址栏和导航栏的高度(safari含标题栏), ios获取的总是竖屏时的宽高,是个定值,安卓因屏幕方向不同宽高不同,跟着变。
> window.innerHeight 浏览器窗口的可视视口高度,包含水平滚动条,安卓上表现正常,ios依然怪异,竖屏正常,ios获取的是转换之前的宽高 (即使使用this.$nextTick)
> document.documentElement.clientHeight 文档可见高度,包含了地址栏和标题栏,表现同 window.innerHeight
解决方法:
1、监听到屏幕转换setTimeout 延迟获取高度
let
2、location.reload() 页面重载
其他不完全方案:touch-action: 设置触摸手势,设为none可阻止下拉,禁掉所有的触摸行为,安卓支持,ios不支持
touch:none // 当触控事件发生在元素上是时,不进行任何操作
touch:auto // 当触控事件发生在元素上时,由浏览器来觉得进行哪些操作。
touch:pan-x // 启用单指水平平移手势
touch:pan-y // 启用单指垂直平
touch:manipulation // 浏览器只允许进行滚动和持续缩放操作。
touch:pinnch-zoom // 启用多手指平移和缩放页面
阻止下拉刷新:
body
测试后成功阻止了移动端chrome的刷新
此文ios测试为iphone8P 版本为12.2,安卓为oppoA73,Andriod版本7.1.1