【HTML5】H5 下拉刷新如何實(shí)現(xiàn)
當(dāng)前位置:點(diǎn)晴教程→知識(shí)管理交流
→『 技術(shù)文檔交流 』
本文轉(zhuǎn)載于稀土掘金技術(shù)社區(qū)——小霖家的混江龍 最近我需要做一個(gè)下拉刷新的功能,實(shí)現(xiàn)功能后我發(fā)現(xiàn),它需要處理的情況還蠻多,于是我整理了這篇文章。 下圖是我實(shí)現(xiàn)的效果,分為三步:開(kāi)始下拉時(shí),屏幕頂部會(huì)出現(xiàn)加載動(dòng)畫(huà);加載過(guò)程中,屏幕頂部高度保持不變;加載完成后,加載動(dòng)畫(huà)隱藏。 首先我會(huì)講解下拉的原理、根據(jù)原理寫(xiě)出初始代碼;然后我會(huì)說(shuō)明代碼存在的缺陷、解決缺陷并做些額外優(yōu)化;最后我會(huì)給出完整代碼,并做一個(gè)總結(jié)。 拳打 H5,腳踢小程序。我是「小霖家的混江龍」,關(guān)注我,帶你了解更多實(shí)用的前端武學(xué)。 下拉的原理如圖所示,藍(lán)色框代表視口,綠色框代表容器,橙色框代表加載動(dòng)畫(huà)。最開(kāi)始時(shí),加載動(dòng)畫(huà)處于視口外;開(kāi)始下拉之后,容器向下移動(dòng),加載動(dòng)畫(huà)從上方進(jìn)入視口;結(jié)束下拉后,容器又開(kāi)始向上移動(dòng),加載動(dòng)畫(huà)也從上方退出視口。 下拉基礎(chǔ)代碼知道原理,我們現(xiàn)在開(kāi)始寫(xiě)實(shí)現(xiàn)代碼,首先是布局的代碼: 布局代碼我們把 box 元素當(dāng)作容器,把 loader-box,loader-box + loading 元素當(dāng)作動(dòng)畫(huà),至于 h1 元素不需要關(guān)注,我們只把它當(dāng)作操作提示。
loader-box 的高度是 80px,按上一節(jié)原理中的分析,初始時(shí)我們需要讓 loader-box 位于視口上方,因此 CSS 代碼中我們需要把它的位置向上移動(dòng) 80px。
loader-box 中的 loader 是純 CSS 的加載動(dòng)畫(huà)。我們利用 border 畫(huà)出的一個(gè)圓形邊框,左、上、右邊框是淺灰色,下邊框是深灰色:
開(kāi)始刷新時(shí),我們給 loader 元素增加一個(gè)動(dòng)畫(huà),讓它從 0 度到 360 度無(wú)限旋轉(zhuǎn),就實(shí)現(xiàn)了加載動(dòng)畫(huà):
邏輯代碼看完布局代碼,我們?cè)倏催壿嫶a。邏輯代碼中,我們要監(jiān)聽(tīng)用戶(hù)的手指滑動(dòng)、實(shí)現(xiàn)下拉手勢(shì)。我們需要用到三個(gè)事件:
從 我們可以先記錄用戶(hù)手指 touchstart 的 clientY 作為開(kāi)始坐標(biāo),記錄用戶(hù)最后一次觸發(fā) touchmove 的 clientY 作為結(jié)束坐標(biāo),二者相減就得到手指移動(dòng)的距離 distanceY。 設(shè)置手指移動(dòng)多少距離,容器就移動(dòng)多少距離,就得到了我們的邏輯代碼:
邏輯代碼實(shí)現(xiàn)一個(gè)簡(jiǎn)陋的下拉效果,當(dāng)然現(xiàn)在還有很多缺陷。 簡(jiǎn)陋下拉效果的 6 個(gè)缺陷之前我們實(shí)現(xiàn)了簡(jiǎn)陋的下拉效果,它還需要解決 6 個(gè)缺陷,才能算一個(gè)完善的功能。 沒(méi)有最小、最大距離限制第一個(gè)缺陷是,下拉沒(méi)有做最小、最大距離的限制。 通常來(lái)說(shuō),我們下拉屏幕時(shí),距離太小應(yīng)該不能觸發(fā)刷新,距離太大也不行,下滑到一定距離后,就應(yīng)該無(wú)法繼續(xù)下滑。 因此我們可以給下拉設(shè)置最小距離限制 解決缺陷關(guān)鍵代碼如下:
加載動(dòng)畫(huà)沒(méi)有停留在視口頂部第二個(gè)缺陷是,下拉沒(méi)有讓加載動(dòng)畫(huà)停留在視口頂部。 我們可以把 end 函數(shù)加以改造,在數(shù)據(jù)還沒(méi)有加載完成時(shí)(用 setTimeout 模擬的),讓加載動(dòng)畫(huà) style 的
重復(fù)觸發(fā)第三個(gè)缺陷是,下拉可以重復(fù)觸發(fā)。 正常來(lái)說(shuō),如果我們已經(jīng)下拉過(guò),數(shù)據(jù)正在加載中時(shí),我們不能繼續(xù)下拉。 我們可以增加一個(gè)加載鎖 loadLock。當(dāng)加載鎖開(kāi)啟時(shí),start,move 和 end 事件都不會(huì)觸發(fā)。
沒(méi)有限制方向第四個(gè)缺陷是,沒(méi)有限制方向。 目前我們的代碼,用戶(hù)上拉也能觸發(fā)。我們可以增加判斷,當(dāng)
你可能會(huì)疑惑,為什么我寧愿寫(xiě)多個(gè)判斷攔截,也不取消監(jiān)聽(tīng)事件。這是因?yàn)?strong style="margin: 0px; padding: 0px; outline: 0px; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important; background-attachment: scroll; background-clip: border-box; background-image: none; background-origin: padding-box; background-position: 0% 0%; background-repeat: no-repeat; background-size: auto; width: auto; height: auto; border-style: none; border-width: 3px; border-color: rgba(0, 0, 0, 0.4); border-radius: 0px;">一旦取消監(jiān)聽(tīng)事件,我們需要考慮在一個(gè)合適的時(shí)間重新監(jiān)聽(tīng),這會(huì)把問(wèn)題變得更復(fù)雜。 沒(méi)有阻止原生滾動(dòng)第五個(gè)缺陷時(shí),我們?cè)诩虞d數(shù)據(jù)時(shí)沒(méi)有阻止原生滾動(dòng)。 雖然我們已經(jīng)阻止了重復(fù)下拉,touchmove 和 touchend 事件被攔截了,但是 H5 原生滾動(dòng)還能用。 我們可以在刷新時(shí)給 body 設(shè)置一個(gè)
沒(méi)有阻止 iOS 橡皮筋效果第 6 個(gè)缺陷是,沒(méi)有阻止 iOS 的橡皮筋效果。 iOS 瀏覽器默認(rèn)滑動(dòng)時(shí)有一個(gè)橡皮筋效果,我們需要阻止它,避免影響我們的下拉手勢(shì)。阻止方式就是給監(jiān)聽(tīng)器設(shè)置
解決完 6 個(gè)缺陷后,我們已經(jīng)得到無(wú)缺陷的下拉刷新功能,但離絲滑的下拉刷新還有一段距離。我們還可以做一些優(yōu)化,讓下拉刷新更完善。 優(yōu)化我們可以做兩個(gè)優(yōu)化,第一個(gè)優(yōu)化是添加阻尼效果: 增加阻尼效果所謂阻尼效果,就是下拉過(guò)程我們可以感受到一股阻力的存在,雖然我們下拉力度是一樣的,但距離的增加速度變慢了。用物理術(shù)語(yǔ)表示的話(huà),就是加速度變小了。 體現(xiàn)到代碼上,我們可以設(shè)置一個(gè)百分比,百分比會(huì)隨著下拉距離增加而減少,把百分比乘以距離當(dāng)作最后的距離。 代碼中百分比
利用角度判斷用戶(hù)下拉意圖第二個(gè)優(yōu)化是利用角度判斷用戶(hù)下拉意圖。 下圖展示了兩種用戶(hù)下拉的情況,β 角度比 α 角度小,角度越小用戶(hù)下拉意圖越明顯、誤觸的可能性更小。 我們可以利用反三角函數(shù)求出角度來(lái)判斷下拉意圖。 JavaScript 中,反正切函數(shù)是 下面的代碼中,我們做了一個(gè)限制,只有角度小于 40 時(shí),我們才認(rèn)為用戶(hù)的真實(shí)意圖是想要下拉刷新。
代碼示例你可以在 codepen[4] 中查看效果,web 端需要按 F12 用手機(jī)瀏覽器打開(kāi)。 總結(jié)本文講解了下拉的原理、并根據(jù)原理寫(xiě)出初始代碼。在初始代碼的基礎(chǔ)上,我解決了 6 個(gè)缺陷、做了 2 個(gè)優(yōu)化,實(shí)現(xiàn)了一個(gè)完善的下拉刷新效果 該文章在 2024/3/30 0:12:59 編輯過(guò) |
關(guān)鍵字查詢(xún)
相關(guān)文章
正在查詢(xún)... |