国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

移動(dòng)端滾動(dòng)研究

ghnor / 1666人閱讀

摘要:還會(huì)有一個(gè)性能上的問題就是當(dāng)頁面的列表過長(zhǎng),元素過多時(shí),在模擬滾動(dòng),下拉刷新這段時(shí)間內(nèi),頁面也會(huì)有卡頓現(xiàn)象,這里采取了一個(gè)優(yōu)化策略即列表較長(zhǎng)時(shí)數(shù)量較多時(shí),在觸發(fā)下拉刷新的時(shí)機(jī)時(shí)將頁面視窗之外的元素隱藏或者存放在里面。

移動(dòng)web滾動(dòng)問題

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

| 機(jī)型(內(nèi)核) | body滾動(dòng) | 局部滾動(dòng) |
| :-: | :-: | :-: |
| ios | 不能實(shí)時(shí)觸發(fā) | 不能實(shí)時(shí)觸發(fā) |
| android | 實(shí)時(shí)觸發(fā)| 實(shí)時(shí)觸發(fā) |
| ios wkwebview內(nèi)核 | 實(shí)時(shí)觸發(fā)| 實(shí)時(shí)觸發(fā) |

不能實(shí)時(shí)觸發(fā)表現(xiàn):只在手指觸摸的屏幕上一直滑動(dòng)時(shí)和滾動(dòng)停止的那一刻才觸發(fā)。

關(guān)于模擬滾動(dòng) 概念

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

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

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

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

方案比較

第一種方案由于慣性滾動(dòng)的時(shí)機(jī)時(shí)由js自己控制所以可以拿到滾動(dòng)觸發(fā)階段的scrolltop值,并且滾動(dòng)的回調(diào)函數(shù)onscroll在滾動(dòng)的階段都會(huì)觸發(fā)。第二種方案相比第一種要劣勢(shì)一些,區(qū)別在于手指離開時(shí),采用的時(shí)css的animation來實(shí)現(xiàn)慣性滾動(dòng),所以無法直接觸發(fā)慣性滾動(dòng)過程中的onscroll事件,只有在animation結(jié)束時(shí)才可以借助animationend來獲取到事件,當(dāng)然也有一種方法可以實(shí)時(shí)獲取滾動(dòng)事件,也是借助于requestanimationframe來不斷的去讀取滾動(dòng)元素的transform來拿到scrolltop同時(shí)觸發(fā)onscroll回調(diào)。

正常滾動(dòng)和模擬滾動(dòng)的性能比較

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

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

滾動(dòng)和下拉刷新

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

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

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

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

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

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

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

下面介紹如何去優(yōu)化scroll事件的觸發(fā),避免scroll事件過度消耗資源:

防抖(Debouncing)和節(jié)流(Throttling)

scroll 事件本身會(huì)觸發(fā)頁面的重新渲染,同時(shí) scroll 事件的 handler 又會(huì)被高頻度的觸發(fā), 因此事件的 handler 內(nèi)部不應(yīng)該有復(fù)雜操作,例如 DOM 操作就不應(yīng)該放在事件處理中。
特別是針對(duì)此類高頻度觸發(fā)事件問題(例如頁面 scroll ,屏幕 resize,監(jiān)聽用戶輸入等)。

防抖(Debouncing)

防抖技術(shù)即是可以把多個(gè)順序地調(diào)用合并成一次,也就是在一定時(shí)間內(nèi),規(guī)定事件被觸發(fā)的次數(shù)。

節(jié)流(Throttling)

防抖函數(shù)確實(shí)不錯(cuò),但是也存在問題,譬如圖片的懶加載,我希望在下滑過程中圖片不斷的被加載出來,而不是只有當(dāng)我停止下滑時(shí)候,圖片才被加載出來。又或者下滑時(shí)候的數(shù)據(jù)的 ajax 請(qǐng)求加載也是同理。這個(gè)時(shí)候,我們希望即使頁面在不斷被滾動(dòng),但是滾動(dòng) handler 也可以以一定的頻率被觸發(fā)(譬如 250ms 觸發(fā)一次),這類場(chǎng)景,就要用到另一種技巧,稱為節(jié)流函數(shù)(throttling)。

節(jié)流函數(shù),只允許一個(gè)函數(shù)在 X 毫秒內(nèi)執(zhí)行一次。

與防抖相比,節(jié)流函數(shù)最主要的不同在于它保證在 X 毫秒內(nèi)至少執(zhí)行一次我們希望觸發(fā)的事件 handler。

關(guān)于防抖動(dòng)與節(jié)流,我的博客文章也有提及。

使用rAF(requestAnimationFrame)觸發(fā)滾動(dòng)事件

如果頁面只需要兼容高版本瀏覽器或應(yīng)用在移動(dòng)端,又或者頁面需要追求高精度的效果,那么可以使用瀏覽器的原生方法 rAF(requestAnimationFrame)。

window.requestAnimationFrame() 這個(gè)方法是用來在頁面重繪之前,通知瀏覽器調(diào)用一個(gè)指定的函數(shù)。這個(gè)方法接受一個(gè)函數(shù)為參,該函數(shù)會(huì)在重繪前調(diào)用。

rAF 常用于 web 動(dòng)畫的制作,用于準(zhǔn)確控制頁面的幀刷新渲染,讓動(dòng)畫效果更加流暢,當(dāng)然它的作用不僅僅局限于動(dòng)畫制作,我們可以利用它的特性將它視為一個(gè)定時(shí)器。(當(dāng)然它不是定時(shí)器)

通常來說,rAF 被調(diào)用的頻率是每秒 60 次,也就是 1000/60 ,觸發(fā)頻率大概是 16.7ms 。(當(dāng)執(zhí)行復(fù)雜操作時(shí),當(dāng)它發(fā)現(xiàn)無法維持 60fps 的頻率時(shí),它會(huì)把頻率降低到 30fps 來保持幀數(shù)的穩(wěn)定。)

var ticking = false; // rAF 觸發(fā)鎖
 
function onScroll(){
  if(!ticking) {
    requestAnimationFrame(realFunc);
    ticking = true;
  }
}
 
function realFunc(){
    // do something...
    console.log("Success");
    ticking = false;
}
// 滾動(dòng)事件監(jiān)聽
window.addEventListener("scroll", onScroll, false);

實(shí)現(xiàn)以16.7ms 觸發(fā)一次 handler,降低了可控性,但是提升了性能和精確度。

從本質(zhì)上而言,我們應(yīng)該盡量去精簡(jiǎn) scroll 事件的 handler ,將一些變量的初始化、不依賴于滾動(dòng)位置變化的計(jì)算等都應(yīng)當(dāng)在 scroll 事件外提前就緒。

避免在scroll 事件中修改樣式屬性 / 將樣式操作從 scroll 事件中剝離

輸入事件處理函數(shù),比如 scroll / touch 事件的處理,都會(huì)在 requestAnimationFrame 之前被調(diào)用執(zhí)行。

因此,如果你在 scroll 事件的處理函數(shù)中做了修改樣式屬性的操作,那么這些操作會(huì)被瀏覽器暫存起來。然后在調(diào)用 requestAnimationFrame 的時(shí)候,如果你在一開始做了讀取樣式屬性的操作,那么這將會(huì)導(dǎo)致觸發(fā)瀏覽器的強(qiáng)制同步布局。

滑動(dòng)過程中嘗試使用 pointer-events: none 禁止鼠標(biāo)事件

pointer-events 是一個(gè) CSS 屬性,可以有多個(gè)不同的值,大概的意思就是禁止鼠標(biāo)行為,應(yīng)用了該屬性后,譬如鼠標(biāo)點(diǎn)擊,hover 等功能都將失效,即是元素不會(huì)成為鼠標(biāo)事件的 target。

pointer-events: none 可用來提高滾動(dòng)時(shí)的幀頻。的確,當(dāng)滾動(dòng)時(shí),鼠標(biāo)懸停在某些元素上,則觸發(fā)其上的 hover 效果,然而這些影響通常不被用戶注意,并多半導(dǎo)致滾動(dòng)出現(xiàn)問題。對(duì) body 元素應(yīng)用 pointer-events: none ,禁用了包括 hover 在內(nèi)的鼠標(biāo)事件,從而提高滾動(dòng)性能。

大概的做法就是在頁面滾動(dòng)的時(shí)候, 給 添加上 .disable-hover 樣式,那么在滾動(dòng)停止之前, 所有鼠標(biāo)事件都將被禁止。當(dāng)滾動(dòng)結(jié)束之后,再移除該屬性。

// css 代碼
.disable-hover,
.disable-hover * {
  pointer-events: none !important;
}
// js 代碼
var body = document.body,
    timer;
window.addEventListener("scroll", function() {
  clearTimeout(timer);
  if(!body.classList.contains("disable-hover")) {
    body.classList.add("disable-hover")
  }
  timer = setTimeout(function(){
    body.classList.remove("disable-hover")
  },500);
}, false);

參考 移動(dòng) Web 的滾動(dòng),高性能滾動(dòng)及頁面渲染優(yōu)化

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/100754.html

相關(guān)文章

  • js移動(dòng)滑倒頂部加載歷史消息解決方案!

    摘要:使用具有回彈效果的滾動(dòng)當(dāng)手指從觸摸屏上移開,內(nèi)容會(huì)繼續(xù)保持一段時(shí)間的滾動(dòng)效果。繼續(xù)滾動(dòng)的速度和持續(xù)的時(shí)間和滾動(dòng)手勢(shì)的強(qiáng)烈程度成正比。 最近做了一個(gè)語音直播聊天的項(xiàng)目,有一個(gè)功能是當(dāng)沒有直播時(shí),進(jìn)入房間可以查看歷史消息,滑動(dòng)到頂部加載之前的歷史消息,我用jquery scroll事件,來判斷是否滾動(dòng)到頂部,問題來了: 首先觸發(fā)請(qǐng)求事件之后,prepend插入到當(dāng)前列表之前,而prepen...

    jackwang 評(píng)論0 收藏0
  • js移動(dòng)滑倒頂部加載歷史消息解決方案!

    摘要:使用具有回彈效果的滾動(dòng)當(dāng)手指從觸摸屏上移開,內(nèi)容會(huì)繼續(xù)保持一段時(shí)間的滾動(dòng)效果。繼續(xù)滾動(dòng)的速度和持續(xù)的時(shí)間和滾動(dòng)手勢(shì)的強(qiáng)烈程度成正比。 最近做了一個(gè)語音直播聊天的項(xiàng)目,有一個(gè)功能是當(dāng)沒有直播時(shí),進(jìn)入房間可以查看歷史消息,滑動(dòng)到頂部加載之前的歷史消息,我用jquery scroll事件,來判斷是否滾動(dòng)到頂部,問題來了: 首先觸發(fā)請(qǐng)求事件之后,prepend插入到當(dāng)前列表之前,而prepen...

    mingde 評(píng)論0 收藏0
  • js移動(dòng)滑倒頂部加載歷史消息解決方案!

    摘要:使用具有回彈效果的滾動(dòng)當(dāng)手指從觸摸屏上移開,內(nèi)容會(huì)繼續(xù)保持一段時(shí)間的滾動(dòng)效果。繼續(xù)滾動(dòng)的速度和持續(xù)的時(shí)間和滾動(dòng)手勢(shì)的強(qiáng)烈程度成正比。 最近做了一個(gè)語音直播聊天的項(xiàng)目,有一個(gè)功能是當(dāng)沒有直播時(shí),進(jìn)入房間可以查看歷史消息,滑動(dòng)到頂部加載之前的歷史消息,我用jquery scroll事件,來判斷是否滾動(dòng)到頂部,問題來了: 首先觸發(fā)請(qǐng)求事件之后,prepend插入到當(dāng)前列表之前,而prepen...

    leejan97 評(píng)論0 收藏0
  • 系列——與眾不同的移動(dòng)底部固定欄 fixed、absolute 兼容 iOS 和 Androi

    摘要:底部定位為的情況下激活輸入框時(shí),底部不會(huì)彈出來合理。后遺癥底部按鈕和輸入框區(qū)域一起隨著滾動(dòng),不再置頂獨(dú)立。當(dāng)滾動(dòng)區(qū)域超過一屏幕時(shí),底部輸入框定位出現(xiàn)錯(cuò)亂。傳統(tǒng)解決辦法通常將底部設(shè)置為,當(dāng)激活輸入框的時(shí)候,將底部定位改為,即可兼容和。 相信我,我分享的和你在其他博客上看到的終極方案是如此的與眾不同! 做過移動(dòng)端開發(fā)的同學(xué),對(duì)底部DOM定位出現(xiàn)的各種奇葩情況已經(jīng)深惡痛絕了吧,底部DOM設(shè)置...

    Doyle 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<