摘要:背景由于移動端原生滾動的局限性以及兼容性,部分特定場景的需求無法滿足。示例模擬滾動知識點(diǎn)通過移動端的系列事件觸發(fā)模擬滾動,獲取手指滑動的偏移量,進(jìn)而改變來進(jìn)行位置偏移。
背景
由于移動端原生滾動的局限性以及兼容性,部分特定場景的需求無法滿足。例如,筆者最近就接了一個需求:整個頁面分為三塊,每塊內(nèi)容的高度不等(但都超過一屏),要求滾動到內(nèi)容的臨界點(diǎn)有一個停頓的效果,下拉可以看到下一塊的部分內(nèi)容,滿足條件則滑到下一塊內(nèi)容。這種場景下,原生的滾動根本無法支持。因此,本文的主角就亮相了:模擬滾動,即盡可能的模擬原生滾動,但是又提供了一些擴(kuò)展,滿足復(fù)雜場景的需求。
本文將從模擬滾動需要實(shí)現(xiàn)的功能、技術(shù)分析和方案來進(jìn)行闡述,通讀本文,讀者將對模擬滾動的常見功能和技術(shù)要點(diǎn)有一定了解。
示例:模擬滾動
知識點(diǎn)通過移動端的touch系列事件觸發(fā)模擬滾動,獲取手指滑動的偏移量,進(jìn)而改變translateY來進(jìn)行位置偏移。
滾動容器滾動容器擁有高度,滾動區(qū)域的高度大于滾動容器,在滾動時,我們對滾動區(qū)域進(jìn)行偏移,以達(dá)到滾動的視覺效果。
通過滾動區(qū)域的高度可以通過offsetHeight獲取,但是在以下情況下會遠(yuǎn)遠(yuǎn)小于實(shí)際高度。
內(nèi)聯(lián)樣式:在DOM節(jié)點(diǎn)生成時,樣式還未渲染完成,此時獲得的高度是默認(rèn)樣式的高度,待樣式渲染完成后,高度可能會有變化
圖片高度:img節(jié)點(diǎn)的高度開始是0,在圖片加載完成時,才會等于圖片高度,因此這里也會存在誤差
慣性滾動我們知道,為了讓滾動更加流暢,原生的滾動會有一個慣性滾動的效果,即手指快速滑動松開后,滾動區(qū)域會繼續(xù)滾動一段距離后停止。
為了實(shí)現(xiàn)這個功能,我們需求知道手指滑動的速度,根據(jù)比率計算目標(biāo)滾動位置,然后驅(qū)動滾動,讓其到達(dá)目標(biāo)位置。
這里筆者嘗試了兩種方案:
通過requestAnimationFrame不斷進(jìn)行偏移,直到到達(dá)目標(biāo)位置
使用transition進(jìn)行過渡,設(shè)置動畫曲線讓其到達(dá)目標(biāo)位置
筆者對比了兩種方案,最終選擇了方案2,原因是transition過渡會更加的流暢,而requestAnimationFrame會有略微的卡頓,但是transition過渡,我們實(shí)時觸發(fā)滾動事件時,不好拿到其當(dāng)前的位置,查閱了一些資料,筆者最終找到了解決方法,即getComputedStyle,這個API可以拿到當(dāng)前頁面渲染的實(shí)時樣式,也就是說,哪怕它處于過渡動畫中,我們可以實(shí)時拿到它的真實(shí)位置。
邊界回彈當(dāng)滾動超出邊界時,通常我們還可以讓其繼續(xù)滾動,但是這時候會設(shè)置阻礙,即滾動速度慢下來,當(dāng)滾動停止時,我們再將其拽回到邊界線。我們可以通過監(jiān)聽transitionend事件來判斷慣性滾動停止,這里的技術(shù)點(diǎn)不做過多分析,感興趣可以在文末中的源碼找答案。
默認(rèn)行為通常情況下,我們需要阻止瀏覽器的默認(rèn)行為(如滾動),但是這樣也會誤殺一些我們需要的默認(rèn)行為(如超鏈接跳轉(zhuǎn)、輸入框聚焦)。
解決方法很簡單,在touchstart觸發(fā)時,我們判斷一下目標(biāo)節(jié)點(diǎn)是否需要阻止默認(rèn)行為,比如說tagName=INPUT,我們不阻止默認(rèn)行為。
點(diǎn)擊事件默認(rèn)行為被阻止,綁定在子節(jié)點(diǎn)上的點(diǎn)擊事件就無法觸發(fā)了,因此這里我們需要判斷一下是否需要觸發(fā)點(diǎn)擊事件??梢酝ㄟ^touch系列事件模擬點(diǎn)擊行為,然后通過document.createEvent("Event")來主動觸發(fā)click事件。
滾動指示器在滾動區(qū)域中,通常在右側(cè)會有一個指示器,用于查看當(dāng)前在整個內(nèi)容區(qū)塊的大概位置。
為了方便使用,筆者注冊了一系列的鉤子,方便使用者調(diào)用,scroll鉤子就是其中之一,在滾動的時候它會實(shí)時觸發(fā),在這里就派上用場了。我們通過scroll鉤子改變指示器的位置,唯獨(dú)要注意的是滾動超出邊界時,指示器會變短然后恢復(fù)。
@axe/scroller基于以上知識點(diǎn)和技術(shù)分析,筆者寫了一個模擬滾動js庫(無任何依賴):https://github.com/ansenhuang/axe/blob/master/packages/scroller/README.md
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/97644.html
摘要:同時,請在其他移動端瀏覽器也這么處理,不要只對蘋果做這些處理。蘋果對于虎頭蛇尾的做法真讓人頭疼,這作風(fēng)跟巨硬真像。 轉(zhuǎn)載請注明英文原文及譯文出處 原文地址:Issues with position fixed & scrolling on iOS 原文作者:Remy Sharp譯文地址:移動端 fixed 和 scroll 問題 譯文作者:鎏金圣手火麒麟 最近在做iOS端的H5頁面...
摘要:同時,請在其他移動端瀏覽器也這么處理,不要只對蘋果做這些處理。蘋果對于虎頭蛇尾的做法真讓人頭疼,這作風(fēng)跟巨硬真像。 轉(zhuǎn)載請注明英文原文及譯文出處 原文地址:Issues with position fixed & scrolling on iOS 原文作者:Remy Sharp譯文地址:移動端 fixed 和 scroll 問題 譯文作者:鎏金圣手火麒麟 最近在做iOS端的H5頁面...
閱讀 1605·2021-09-23 11:21
閱讀 2365·2021-09-07 10:13
閱讀 847·2021-09-02 10:19
閱讀 1143·2019-08-30 15:44
閱讀 1734·2019-08-30 13:18
閱讀 1921·2019-08-30 11:15
閱讀 1117·2019-08-29 17:17
閱讀 2026·2019-08-29 15:31