移動(dòng)web之滾動(dòng)知識(shí)篇

2022-06-14    分類(lèi): 網(wǎng)站建設(shè)

創(chuàng)新互聯(lián)編者為大家整理了手機(jī)WAP網(wǎng)站知識(shí)——《移動(dòng)web之滾動(dòng)知識(shí)篇

知識(shí)點(diǎn)1:移動(dòng)web滾動(dòng)問(wèn)題

在移動(dòng)端,使用滾動(dòng)來(lái)處理業(yè)務(wù)邏輯的情況有很多,例如列表的滾動(dòng)加載數(shù)據(jù),下拉刷新等等都需要利用滾動(dòng)的相關(guān)知識(shí),但是滾動(dòng)事件在不同的移動(dòng)端機(jī)型卻又有不同的表現(xiàn),下面就來(lái)一一總結(jié)一下。

滾動(dòng)事件:即onscroll事件,形成原因通俗解釋是當(dāng)子元素的高度超過(guò)父元素的高度時(shí)且父元素的高度時(shí)定值window除外,就會(huì)形成滾動(dòng)條,滾動(dòng)分為兩種:局部滾動(dòng)和body滾動(dòng)。

onscroll方法: 一般情況下當(dāng)我們需要監(jiān)聽(tīng)一個(gè)滾動(dòng)事件時(shí)通常會(huì)用到onscroll方法來(lái)監(jiān)聽(tīng)滾動(dòng)事件的觸發(fā)。 如果在瀏覽器上調(diào)試這個(gè)方法在瀏覽器上很好用,但是如果跑在手機(jī)端就沒(méi)有想象中的效果了。

body滾動(dòng):在移動(dòng)端如果使用body滾動(dòng),意思就是頁(yè)面的高度由內(nèi)容自動(dòng)撐大,body自然形成滾動(dòng)條,這時(shí)我們監(jiān)聽(tīng)window.onscroll,發(fā)現(xiàn)onscroll并沒(méi)有實(shí)時(shí)觸發(fā),只在手指觸摸的屏幕上一直滑動(dòng)時(shí)和滾動(dòng)停止的那一刻才觸發(fā),采用了wk內(nèi)核的webview除外。



body滾動(dòng)
局部滾動(dòng)

局部滾動(dòng):在移動(dòng)端如果使用局部滾動(dòng),意思就是我們的滾動(dòng)在一個(gè)固定寬高的div內(nèi)觸發(fā),將該div設(shè)置成overflow:scroll/auto;來(lái)形成div內(nèi)部的滾動(dòng),這時(shí)我們監(jiān)聽(tīng)div的onscroll發(fā)現(xiàn)觸發(fā)的時(shí)機(jī)區(qū)分android和ios兩種情況,具體可以看下面表格:

不同機(jī)型onscroll事件觸發(fā)情況:

body滾動(dòng) 局部滾動(dòng)
ios 不能實(shí)時(shí)觸發(fā) 不能實(shí)時(shí)觸發(fā)
android 實(shí)時(shí)觸發(fā) 實(shí)時(shí)觸發(fā)
ioswkwebview內(nèi)核 實(shí)時(shí)觸發(fā) 實(shí)時(shí)觸發(fā)

wkwebview內(nèi)核:這里說(shuō)明一下關(guān)于ios的wkwebview內(nèi)核是ios從ios8開(kāi)始提供的新型webview內(nèi)核,和之前的uiwebview相比,性能要好,具體大家可以自行查看關(guān)于wkwebview的相關(guān)概念。

body滾動(dòng)和局部滾動(dòng)demo:這里我需要指出的是在采用wkwebview內(nèi)核的頁(yè)面中scroll是可以實(shí)時(shí)觸發(fā)的,如果使用的是原本的uiwebview則不能夠?qū)崟r(shí)觸發(fā),手q目前使用的是uiwebview而新版微信使用的是wkwebview,大家可以分別使用來(lái)嘗試一下下面的demo:


局部滾動(dòng)
body滾動(dòng)

分別用ios手q和微信和android手q體驗(yàn)會(huì)有不同的結(jié)果。

知識(shí)點(diǎn)2:關(guān)于模擬滾動(dòng)

正常的滾動(dòng):我們平時(shí)使用的scroll,包括上面講的滾動(dòng)都屬于正常滾動(dòng),利用瀏覽器自身提供的滾動(dòng)條來(lái)實(shí)現(xiàn)滾動(dòng),底層是由瀏覽器內(nèi)核控制。

模擬滾動(dòng):最典型的例子就是iscroll(AlloyTouch)了,原理一般有兩種:

1). 監(jiān)聽(tīng)滾動(dòng)元素的touchmove事件,當(dāng)事件觸發(fā)時(shí)修改元素的transform屬性來(lái)實(shí)現(xiàn)元素的位移,讓手指離開(kāi)時(shí)觸發(fā)touchend事件,然后采用requestanimationframe來(lái)在一個(gè)線型函數(shù)下不斷的修改元素的transform來(lái)實(shí)現(xiàn)手指離開(kāi)時(shí)的一段慣性滾動(dòng)距離。

2).監(jiān)聽(tīng)滾動(dòng)元素的touchmove事件,當(dāng)事件觸發(fā)時(shí)修改元素的transform屬性來(lái)實(shí)現(xiàn)元素的位移,讓手指離開(kāi)時(shí)觸發(fā)touchend事件,然后給元素一個(gè)css的animation,并設(shè)置好duration和function來(lái)實(shí)現(xiàn)手指離開(kāi)時(shí)的一段慣性距離。

方案區(qū)別:這兩種方案對(duì)比起來(lái)各有好處,第一種方案由于慣性滾動(dòng)的時(shí)機(jī)時(shí)由js自己控制所以可以拿到滾動(dòng)觸發(fā)階段的scrolltop值,并且滾動(dòng)的回調(diào)函數(shù)onscroll在滾動(dòng)的階段都會(huì)觸發(fā)。

第二種方案相比第一種要劣勢(shì)一些,區(qū)別在于手指離開(kāi)時(shí),采用的時(shí)css的animation來(lái)實(shí)現(xiàn)慣性滾動(dòng),所以無(wú)法直接觸發(fā)慣性滾動(dòng)過(guò)程中的onscroll事件,只有在animation結(jié)束時(shí)才可以借助animationend來(lái)獲取到事件,當(dāng)然也有一種方法可以實(shí)時(shí)獲取滾動(dòng)事件,也是借助于requestanimationframe來(lái)不斷的去讀取滾動(dòng)元素的transform來(lái)拿到scrolltop同時(shí)觸發(fā)onscroll回調(diào)。

demo體驗(yàn):關(guān)于模擬滾動(dòng)和正常滾動(dòng),兩者在性能上差別還是比較明顯的,下面時(shí)兩個(gè)demo,可以掃描體驗(yàn)一下:


正常滾動(dòng)模擬滾動(dòng)

衡量指標(biāo):衡量滾動(dòng)是否流暢的指標(biāo)fps,我這邊也統(tǒng)計(jì)了一下正常滾動(dòng)和模擬滾動(dòng)的fps數(shù)據(jù):


正常滾動(dòng)

模擬滾動(dòng)

結(jié)論: 模擬滾動(dòng)的fps值波動(dòng)較大,這樣滾動(dòng)起來(lái)會(huì)有明顯的卡頓感覺(jué),各位體驗(yàn)的時(shí)候如果滾動(dòng)超過(guò)10屏之后就可以明顯感覺(jué)到兩著的區(qū)別。

在使用模擬滾動(dòng)時(shí),瀏覽器在js層面會(huì)消耗更多的性能去改變dom元素的位置,在dom復(fù)雜層級(jí)深的頁(yè)面更為高,所以在長(zhǎng)列表滾動(dòng)時(shí)還要使用正常滾動(dòng)更好。

知識(shí)點(diǎn)3:滾動(dòng)和下拉刷新

下拉刷新的元素在頁(yè)面頂部,正常瀏覽時(shí)不可見(jiàn)的。

當(dāng)在頁(yè)面頂部往下滾動(dòng)時(shí)出現(xiàn)下拉刷新元素,當(dāng)手指離開(kāi)時(shí)收起。

以上兩點(diǎn)時(shí)實(shí)現(xiàn)一個(gè)下拉刷新組件的基本步驟,結(jié)合我們上述關(guān)于滾動(dòng)的描述,我們可以這樣實(shí)現(xiàn)下拉刷新:


方案1:借助iscroll的原理,整個(gè)頁(yè)面使用模擬滾動(dòng),將下拉刷新元素放在頂部,當(dāng)頁(yè)面滾動(dòng)到頂部下拉時(shí),下拉刷新元素隨著頁(yè)面的滾動(dòng)出現(xiàn),當(dāng)手指離開(kāi)時(shí)收回,此方案實(shí)現(xiàn)起來(lái)較為簡(jiǎn)單直接借助iscoll即可,但是使用了模擬滾動(dòng)之后在正常的列表滾動(dòng)時(shí)性能上不如正常滾動(dòng)。

方案2:頁(yè)面使用正常滾動(dòng),將下拉刷新元素放置在頂部top值為負(fù)值(正常情況下不可見(jiàn)),當(dāng)頁(yè)面處于頂部時(shí)下拉,這時(shí)監(jiān)聽(tīng)touchmove事件,修改scrollcontent的tranlateY值,同時(shí)修改下拉刷新元素的tranlateY值,將兩者同時(shí)位移來(lái)將下拉刷新元素顯示出來(lái),手指離開(kāi)時(shí)(touchend)收回,這種方案滿足了在正常列表滾動(dòng)時(shí)使用原生的滾動(dòng)節(jié)省性能,只在下拉刷新時(shí)使用模擬滾動(dòng)來(lái)實(shí)現(xiàn)效果。

方案3:方案2的改良版,唯一不同是將下拉刷新元素和scrollcontent放在一個(gè)div里,將下拉刷新元素的margintop設(shè)為負(fù)值,在下拉刷新時(shí),只需要修改scrollcontent一個(gè)元素的tranlateY值即可實(shí)現(xiàn)下拉,在性能上要比方案2好。


性能問(wèn)題:在采用了上述方案之后,還會(huì)有一個(gè)性能上的問(wèn)題就是:當(dāng)頁(yè)面的列表過(guò)長(zhǎng),dom元素過(guò)多時(shí),在模擬滾動(dòng),下拉刷新這段時(shí)間內(nèi),頁(yè)面也會(huì)有卡頓現(xiàn)象,這里采取了一個(gè)

優(yōu)化策略:

1) 列表較長(zhǎng)時(shí)dom數(shù)量較多時(shí),在觸發(fā)下拉刷新的時(shí)機(jī)時(shí)將頁(yè)面視窗之外的dom元素隱藏或者存放在fragment里面。

2) 在刷新完成之后手指離開(kāi)(touchend)時(shí)將隱藏的元素顯示出來(lái)。

3) 需要注意的是,隱藏和顯示視窗外的元素這個(gè)操作在下拉刷新時(shí)只會(huì)執(zhí)行一次,并且只有在下拉刷新時(shí)才會(huì)執(zhí)行。

AlloyPullRefresh(基于上述知識(shí)點(diǎn)開(kāi)發(fā)的組件)

  • 定義下拉刷新元素樣式
  • 下拉刷新事件回調(diào)
  • 支持zepto版本和react版本

網(wǎng)站題目:移動(dòng)web之滾動(dòng)知識(shí)篇
當(dāng)前網(wǎng)址:http://www.bm7419.com/news4/167404.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App設(shè)計(jì)網(wǎng)站導(dǎo)航、商城網(wǎng)站手機(jī)網(wǎng)站建設(shè)、軟件開(kāi)發(fā)、外貿(mào)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)