摘要:腦洞爆炸的背景最近開發(fā)項(xiàng)目動(dòng)效開發(fā)越來越多部分動(dòng)效需要在頁面滑動(dòng)的時(shí)候執(zhí)行一定的效果但是發(fā)現(xiàn)在移動(dòng)端很多時(shí)候頁面滑動(dòng)的速度快的時(shí)候,動(dòng)效呈現(xiàn)的不穩(wěn)定性越明顯,會(huì)不流暢雖然使用的過渡可以從視覺層面解決這個(gè)問題,但是并不能根治,于是乎想到了一個(gè)
腦洞爆炸的背景
最近開發(fā)項(xiàng)目動(dòng)效開發(fā)越來越多 ;
部分動(dòng)效需要在頁面滑動(dòng)的時(shí)候執(zhí)行一定的效果;
但是發(fā)現(xiàn)在移動(dòng)端 很多時(shí)候頁面滑動(dòng)的速度快的時(shí)候 , 動(dòng)效呈現(xiàn)的不穩(wěn)定性越明顯 , 會(huì)不流暢; 雖然使用css3的過渡可以從視覺層面解決這個(gè)問題 , 但是并不能根治, 于是乎想到了一個(gè)方案。。。
h5新增的用于刷幀的api , 大家可以網(wǎng)上找到很多相關(guān)教程 , 用法及其簡(jiǎn)單 , 跟使用setTimeOut一樣; 此api的初衷本人理解為用于更好的執(zhí)行動(dòng)畫 , 而找到的一句話 “執(zhí)行渲染下一幀之前的動(dòng)作”可能更好的幫助你理解這個(gè)api;
方案而之前說的移動(dòng)端動(dòng)畫不流暢的原因是因?yàn)榭焖倩瑒?dòng)的時(shí)候 , 兩次出發(fā)scroll之間的“間距”越來越大,而導(dǎo)致需要根據(jù)滑動(dòng)計(jì)算的精度越來越不準(zhǔn) , 我們當(dāng)然希望每滑動(dòng)1px執(zhí)行一次scroll是最完美的啦~(雖然基本不可能)
于是乎 , 想到了一個(gè)方案?!
可以在window.scroll開始的時(shí)候開啟RAF,在window.scroll結(jié)束的時(shí)候關(guān)閉RAF , 所有需要執(zhí)行在scroll中的函數(shù)搬到RAF中執(zhí)行就好了
事實(shí)上實(shí)驗(yàn)結(jié)果是成功的
每次window.scroll的時(shí)候在頁面插入一次scroll字樣 , 每次raf執(zhí)行的時(shí)候插入raf字樣 , 在保證一段scroll過程中只存在唯一一個(gè)RAF , 輸出如上圖
事實(shí)證明 ios微信環(huán)境下 , raf觸發(fā)的頻率在快速滑動(dòng)頁面的時(shí)候確實(shí)高于scroll;
實(shí)現(xiàn)唯一的一個(gè)實(shí)現(xiàn)難點(diǎn)在于 scrollend如何監(jiān)聽
在每一次scroll的時(shí)候 , 開啟一個(gè)50ms的定時(shí)器 , 定時(shí)器認(rèn)定為scroll結(jié)束 , 但是每次滑動(dòng)都創(chuàng)建定時(shí)器就亂套了 , 所以要在創(chuàng)建定時(shí)器之前先清除定時(shí)器;
捋一下:
第一次scroll, 清除一個(gè)不存在的定時(shí)器 , 然后創(chuàng)建定時(shí)器 , 50ms之后執(zhí)行的就是scroll結(jié)束
第二次scroll , 清除第一次創(chuàng)建的定時(shí)器 , 創(chuàng)建一個(gè)定時(shí)器 , 50ms之后執(zhí)行的就是scroll結(jié)束
。。。。
最后一次scroll , 清除倒數(shù)第二次創(chuàng)建的定時(shí)器 , 創(chuàng)建一個(gè)定時(shí)器 , 由于沒有下一次scroll了 , 那么這個(gè)定時(shí)器就真的是最后一次scroll了
于是通過這樣的方案迂回形成了scrollEnd , 雖然有50ms的誤差~
然后代碼如下 :
var rAF = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) { window.setTimeout(callback, 1000 / 60); }; var cancelRAF = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.webkitCancelRequestAnimationFrame || window.mozCancelRequestAnimationFrame || window.oCancelRequestAnimationFrame || window.msCancelRequestAnimationFrame || clearTimeout; class BetterScroll { constructor() { let sy = window.scrollY; this.onScroll = this.onScroll; this.onScrollEnd = this.onScrollEnd; this.scrollList = []; this.scrollEndList = []; this.scrollTimer = null; this.nowWsy = sy; this.lastY = sy; this.direction = 0; this.rafMark = null; this.rafingMark = false; this.gap = 0; this.bindEvent(); } onScroll(cb) { if (typeof cb !== "function") { return; } this.scrollList.push(cb); } onScrollEnd(cb) { if (typeof cb !== "function") { return; } this.scrollEndList.push(cb); } scrollEnd() { let winInfo = { sy : this.nowWsy, gap : Math.abs(this.gap), dir : this.direction, } for (let i = 0, len = this.scrollEndList.length; i < len; i++) { try { this.scrollEndList[i](winInfo); } catch (error) { console.warn(error) } } } rafing() { this.nowWsy = window.scrollY; this.gap = this.nowWsy - this.lastY; // 1為向上滑動(dòng) -1 為向下滑動(dòng) !!this.gap && (this.direction = (((this.gap >= 0) | 0 ) - 0.5) * 2); this.lastY = this.nowWsy; let winInfo = { sy : this.nowWsy, //當(dāng)前window的scrollY gap : Math.abs(this.gap), //上次到這次滑動(dòng)的距離 dir : this.direction, // 滑動(dòng)方向 } for (let i = 0, len = this.scrollList.length; i < len; i++) { try { this.scrollList[i](winInfo); } catch (error) { console.warn(error) } } this.startRaf(); } startRaf() { let _this = this; this.rafMark = rAF(function () { _this.rafing(); }) } bindEvent() { let _this = this; window.addEventListener("scroll", function () { clearTimeout(_this.scrollTimer); if (!_this.rafingMark) { _this.startRaf(); _this.rafingMark = true; } _this.scrollTimer = setTimeout(function () { cancelRAF(_this.rafMark); _this.scrollEnd(); _this.rafingMark = false; }, 50); }, 0) } } let btScroll = new BetterScroll(); export default btScroll;
用法 :
組建拋出btScroll對(duì)象 ,
提供兩個(gè)方法
btScroll.onScroll(callback); window正在scrolling的函數(shù) , 回調(diào)函數(shù)接受參數(shù) winInfo btScroll.onScrollEnd(callback); window滑動(dòng)結(jié)束的函數(shù) , 回調(diào)函數(shù)接受參數(shù) winInfo winInfo : { sy : window的scrollY值, gap : 上一次scroll到這一次scroll之間的差值絕對(duì)值, dir : window的滑動(dòng)方向 1為瀏覽器滾動(dòng)條向下滾動(dòng) , -1為瀏覽器滾動(dòng)條向上滾動(dòng), }
歡迎各位大大交流 , 有更好的腦洞和哪里寫的不足的地方歡迎留言討論!
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/90308.html
摘要:腦洞爆炸的背景最近開發(fā)項(xiàng)目動(dòng)效開發(fā)越來越多部分動(dòng)效需要在頁面滑動(dòng)的時(shí)候執(zhí)行一定的效果但是發(fā)現(xiàn)在移動(dòng)端很多時(shí)候頁面滑動(dòng)的速度快的時(shí)候,動(dòng)效呈現(xiàn)的不穩(wěn)定性越明顯,會(huì)不流暢雖然使用的過渡可以從視覺層面解決這個(gè)問題,但是并不能根治,于是乎想到了一個(gè) 腦洞爆炸的背景 最近開發(fā)項(xiàng)目動(dòng)效開發(fā)越來越多 ; 部分動(dòng)效需要在頁面滑動(dòng)的時(shí)候執(zhí)行一定的效果;但是發(fā)現(xiàn)在移動(dòng)端 很多時(shí)候頁面滑動(dòng)的速度快的時(shí)候 ,...
摘要:腦洞爆炸的背景最近開發(fā)項(xiàng)目動(dòng)效開發(fā)越來越多部分動(dòng)效需要在頁面滑動(dòng)的時(shí)候執(zhí)行一定的效果但是發(fā)現(xiàn)在移動(dòng)端很多時(shí)候頁面滑動(dòng)的速度快的時(shí)候,動(dòng)效呈現(xiàn)的不穩(wěn)定性越明顯,會(huì)不流暢雖然使用的過渡可以從視覺層面解決這個(gè)問題,但是并不能根治,于是乎想到了一個(gè) 腦洞爆炸的背景 最近開發(fā)項(xiàng)目動(dòng)效開發(fā)越來越多 ; 部分動(dòng)效需要在頁面滑動(dòng)的時(shí)候執(zhí)行一定的效果;但是發(fā)現(xiàn)在移動(dòng)端 很多時(shí)候頁面滑動(dòng)的速度快的時(shí)候 ,...
摘要:防抖和節(jié)流嚴(yán)格算起來應(yīng)該屬于性能優(yōu)化的知識(shí),但實(shí)際上遇到的頻率相當(dāng)高,處理不當(dāng)或者放任不管就容易引起瀏覽器卡死。 防抖和節(jié)流嚴(yán)格算起來應(yīng)該屬于性能優(yōu)化的知識(shí),但實(shí)際上遇到的頻率相當(dāng)高,處理不當(dāng)或者放任不管就容易引起瀏覽器卡死。所以還是很有必要早點(diǎn)掌握的。(信我,你看完肯定就懂了) 從滾動(dòng)條監(jiān)聽的例子說起 先說一個(gè)常見的功能,很多網(wǎng)站會(huì)提供這么一個(gè)按鈕:用于返回頂部。showImg(ht...
摘要:原文鏈接前言在移動(dòng)端網(wǎng)頁中,下拉刷新和上拉加載更多數(shù)據(jù)的交互方式出現(xiàn)頻率很高,開源社區(qū)也有很多類似的解決方案,如,庫等。 原文鏈接:justrockit.top 前言 在移動(dòng)端H5網(wǎng)頁中,下拉刷新和上拉加載更多數(shù)據(jù)的交互方式出現(xiàn)頻率很高,開源社區(qū)也有很多類似的解決方案,如iscroll,pulltorefresh.js庫等。下面是對(duì)這兩種常見交互基本實(shí)現(xiàn)原理的闡述。 實(shí)現(xiàn)原理 下拉刷新...
閱讀 1393·2021-11-22 15:11
閱讀 2838·2019-08-30 14:16
閱讀 2755·2019-08-29 15:21
閱讀 2914·2019-08-29 15:11
閱讀 2451·2019-08-29 13:19
閱讀 2985·2019-08-29 12:25
閱讀 417·2019-08-29 12:21
閱讀 2829·2019-08-29 11:03