最近作了一个需求,须要作吸顶的效果,在安卓机器和IOS高版本系统下,能改完美实现吸顶效果,可是在低版本的IOS中,却遇到了坑,当我滚动到吸顶的位置的时候,它仍然没有吸顶,只有滚动中止的时候才吸顶。
vue
google分析了缘由,有两种缘由会致使这种状况。react
若是你监听滚动是使用addEventListener的方式,那么很遗憾的告诉你,你中招了,经过这种方式绑定滚动事件,如标题所示,只会在滚动中止的时候才触发一次,相似防抖操做,只有在最后一次触发。ios
可是,若是你用window.onscroll的方式监听滚动的话,就能够在滚动的过程当中触发scroll事件了,是否是很神奇?web
网上还有说用touchmove来监听,也是能够在滚动的时候触发事件的,可是touchmove有两个缺点是:bash
然而,我改成onscroll监听滚动了,但是我仍是没法及时更新吸顶元素,仍是和用addEventListener来监听scroll的效果同样,在滚动中止的时候才会吸顶。这就要导出第二个会致使这个现象的缘由了。框架
会出现这个的缘由,估计和第一个缘由同样,IOS想要作一些优化,避免一些重复的操做,就和咱们作函数节流同样的思想,可是出这个方案的大神,你就没想到这样一刀切的方式会让咱们开发者遇到不少坑吗(借机吐槽下)?个人技术栈是用vue,而咱们知道,vue是异步更新dom的,因此我在onscroll里面经过vue更新视图的操做,都会被ios阻塞,只有滚动中止后才会拿出来执行。dom
顺便说一句,若是你的滚动处理函数使用防抖来优化,那效果仍是同样,由于防抖的实现原理是setTimeout,而setTimeout也是异步操做,都会被IOS阻塞。异步
具体看你们的状况,若是是第一种缘由致使的,请使用window.onscroll来监听滚动,若是是第二种缘由,请避免在scroll事件中使用异步操做,而若是你是使用vue或者react这些框架,它们都会异步去更新dom。函数
根据是不是uiwebview,选择性地使用正常的方式和原生js操做dom更新视图优化
if (isUIWebView) {
window.onscroll = function() {
// 使用原生js操做dom
}
} else {
// 正常的状况,使用防抖、vue|react去操做dom
window.addEventListener('scroll', this.scrollHandler)
}
复制代码
使用第三方滚动插件模拟滚动,好比iscroll之类的。
function getScrollTop(el) {
if (!el) {
return document.documentElement.scrollTop || window.pageYOffset || document.body.scrollTop;
}
return el.scrollTop;
}
复制代码