最近作了一個需求,須要作吸頂的效果,在安卓機器和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;
}
複製代碼