javascript - 前端: 移动端onscroll事件在部分浏览器内不能实时触发

查看:753
本文介绍了javascript - 前端: 移动端onscroll事件在部分浏览器内不能实时触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问 题

开发情景如下:

  • 使用React开发移动端web app

  • 需要监听容器元素的滚动距离来实现 实时 加载对应子元素

  • 可滚动的容器元素非全局body

  • 滚动方式采用原生滚动,由 css 设定 body{-webkit-overflow-scrolling:touch} 实现弹性滚动

  • 事件监听采用过: react的onScroll事件, JQ的scroll方法及原生onscroll事件,均会出现以下问题

出现问题:

  • 在部分浏览器(例如:safari)下,手指触发滚动后抬起,此时元素会处于弹性滚动过程,此时这部分浏览器依旧能 实时 监听到滚动事件并做出响应,另外一部分浏览器(例如:UC及微信内嵌浏览器等),当抬手让元素处于弹性滚动过程时,浏览器并不能实时进行事件响应,而是当滚动完全停止后浏览器才会执行事件回调

希望懂的朋友能帮忙解决下,万分感谢!

解决方案

根据多方面的测试及咨询UC浏览器方的工程师,出现该问题的原因可以参考这个链接:http://andyshora.com/mobile-scroll-event-problems.html,个人不才,没有能找到好的兼容方案,下面是对自己这几天做的尝试的一个总结:

原因分析:

  • ios的webview 内核 设定了其在进行momentum scrolling(弹性滚动)时,会停止所有的 事件响应DOM操作引起的页面渲染 (亲测),故 onscroll 不能实时响应

曾做兼容方案:

  1. 使用 ontouchmove 去替代 nscroll ,虽然能更频繁的触发事件,但是这边的项目需求是实时响应滚动事件的同时,还要对页面元素进行重定位的DOM操作,由上述原因可知,在滚动过程中,页面会停止一切关于DOM方面的操作,所以若使用 ontouchmove 去实现的话,在按住屏幕进行滑动的时候,屏幕会出现元素抖动的情况(事件触发与DOM操作间具有几十毫秒的时间差),兼容失败

  2. 使用 iscroll 的probe版本,该版本能实时探查到滚动的距离,但该钩子函数是实时去关注 requestAnimationFrame 下的状态,所以对浏览器的版本性能消耗很大,加上 react 的 DOM 操作,安卓机根本动不了,兼容失败

  3. 使用 swiper 插件,在启动 freeMode 模式时模拟原生的弹性滚动( swiper 模拟原生滚动的方案能兼容较多的安卓机型不出现bug,推荐), 因为 swiper 没有实时监听滚动位置的功能,故我监听滚动开始及结束后的事件,通过 setInterval 及一些计算去实现滚动条的监听,但因为 react 元素的变化量比较大,导致 swiper 在移动端时对父容器的计算速率达到了一个瓶颈,依旧出现很卡顿的现象,兼容失败

  4. fallback方案,安卓端使用原生onscroll实现,ios直接加载全部子元素,毕竟ios的性能方面还是比较好的,有更好的方案后续再更.

该回答如有错误,望请各位多多指正.

这篇关于javascript - 前端: 移动端onscroll事件在部分浏览器内不能实时触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆