摘要:這個(gè)來(lái)的莫名其妙,問(wèn)了一圈人也沒(méi)什么思路,后來(lái)自己上網(wǎng)搜,在一個(gè)頁(yè)面上找到一段關(guān)于的觸控板的手勢(shì)滑動(dòng)會(huì)瘋狂觸發(fā)滾輪事件的記錄,但是輪到具體的解決方案就語(yǔ)焉不詳了。
頭幾天官網(wǎng)剛上線,就接到投訴說(shuō)有問(wèn)題。過(guò)去一看,我靠什么鬼?!Mac下用觸控板一滑到底,——首頁(yè)上用iscroll寫(xiě)的翻頁(yè)效果直接全軍覆沒(méi)。
這個(gè)bug來(lái)的莫名其妙,問(wèn)了一圈人也沒(méi)什么思路,后來(lái)自己上網(wǎng)搜,在一個(gè)頁(yè)面上找到一段關(guān)于Mac的觸控板的手勢(shì)滑動(dòng)會(huì)瘋狂觸發(fā)滾輪事件的記錄,但是輪到具體的解決方案就語(yǔ)焉不詳了。沒(méi)轍,靠天沒(méi)用,還是靠自己吧~
這里先簡(jiǎn)單介紹下。出問(wèn)題的首頁(yè)用的是iscroll插件,用snap屬性做的整屏翻頁(yè)的效果,翻頁(yè)用鼠標(biāo)滾輪驅(qū)動(dòng),這塊用的是MDN上的一個(gè)滾輪事件的兼容代碼,回調(diào)使用iscroll的接口完成向上/向下翻頁(yè)的效果。
回到這個(gè)問(wèn)題上。一開(kāi)始我想用事件防抖解決,于是用setTimeout()自己寫(xiě)了個(gè):觸發(fā)事件后先進(jìn)入延時(shí),延時(shí)后執(zhí)行函數(shù);如果在延時(shí)內(nèi)仍有事件觸發(fā),則取消原有的延時(shí)重新計(jì)時(shí)。
// 打底用的zepto.js,addWheelListener是滾輪事件的兼容插件,下同~ var wheelTimer = false; var wheelSlide = function (e) { e.preventDefault(); clearTimeout(timer); if (e.deltaY > 0) { wheelTimer = setTimeout(function(){ iScroll.next(); }, 100); } else if (e.deltaY < 0 && iScroll.currentPage.pageY != 0) { wheelTimer = setTimeout(function(){ iScroll.prev(); }, 100); } } addWheelListener($("body")[0], wheelSlide);
我本意是用延時(shí)抵消掉重復(fù)觸發(fā)的滾輪事件,最后合成一個(gè)事件觸發(fā),沒(méi)想到測(cè)試之后,Mac上的問(wèn)題并沒(méi)有解決。
于是我想,用事件防抖的思路處理應(yīng)該還是不對(duì),即便是延遲時(shí)間較短,如果事件持續(xù)觸發(fā)的話肯定翻頁(yè)還是會(huì)被無(wú)限的延遲阻塞掉,至此我想換用事件節(jié)流再試試。在找資料的時(shí)候,意外發(fā)現(xiàn)了Underscore.js這個(gè)工具庫(kù),里邊不僅有現(xiàn)成的節(jié)流和防抖(中文文檔里用的是“防反跳”)函數(shù)可以用,而且還支持鏈?zhǔn)秸{(diào)用,并且壓縮版本也才十幾k,正合我意。
說(shuō)干就干,馬上用Underscore擼了個(gè)事件節(jié)流版的:
var wheelSlide = _(function (e) { e.preventDefault(); if (e.deltaY > 0) { iScroll.next(); } else if (e.deltaY < 0 && iScroll.currentPage.pageY != 0) { iScroll.prev(); } }).throttle(400);//這里毫秒數(shù)用了400,大概相當(dāng)于一個(gè)短動(dòng)畫(huà)的執(zhí)行時(shí)間 addWheelListener($("body")[0], wheelSlide);
鏈?zhǔn)綄?xiě)法看上去還挺不錯(cuò)的!進(jìn)本機(jī)瀏覽器(PC)……嗯?為啥最后會(huì)跳一下?趕緊翻文檔,又加了個(gè)參數(shù)上去:
var wheelSlide = _(function (e) { e.preventDefault(); if (e.deltaY > 0) { iScroll.next(); } else if (e.deltaY < 0 && iScroll.currentPage.pageY != 0) { iScroll.prev(); } }).throttle(400, {trailing: false}); addWheelListener($("body")[0], wheelSlide);
這回PC上倒是正常了,Mac也從一滑到底變成了有“段落感”的跳動(dòng),但結(jié)果還是不對(duì)……
一狠心把毫秒數(shù)改成了5000,結(jié)果呢:還、是、不、對(duì)、、、。。。
(//陷入循環(huán)懵逼狀態(tài)ing……)
痛定思痛,一定是文檔看的不夠多!于是又啃了一遍Underscore.js的文檔(雖然是翻譯的,囧……),發(fā)現(xiàn)防抖居然有個(gè)[immediate]參數(shù),是可以優(yōu)先執(zhí)行的!大喜過(guò)望~接著擼:
var wheelSlide = _(function (e) { e.preventDefault(); if (e.deltaY > 0) { wScroll.next(); } else if (e.deltaY < 0 && wScroll.currentPage.pageY != 0) { wScroll.prev(); } }).debounce(600, true);// 本來(lái)想改回400的,有點(diǎn)心虛所以又加了200…… addWheelListener($("body")[0], wheelSlide);
居然PC和Mac都能一頁(yè)頁(yè)的翻頁(yè)了有!沒(méi)!有!不過(guò)翻頁(yè)的動(dòng)作還有點(diǎn)遲滯,于是果斷把毫秒數(shù)改小:400、200、100,……Bingo!
最終代碼:
var wheelSlide = _(function (e) { e.preventDefault(); if (e.deltaY > 0) { wScroll.next(); } else if (e.deltaY < 0 && wScroll.currentPage.pageY != 0) { wScroll.prev(); } }).debounce(50, true); addWheelListener($("body")[0], wheelSlide);
總結(jié):
Mac觸控板bug踩坑 +1;
理解了事件節(jié)流和事件防抖的概念;
Underscore.js真好用;
感謝git把每次的修改都記了下來(lái)。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/81573.html
摘要:返回的位置矩陣返回的方向矩陣返回軸每秒的角加速度返回軸每秒的角速度返回軸每秒的線性加速度返回軸的線性速度與只有的如和的只包含方向矩陣,因此為而為而的如和由于和兼具,因此和都為。 showImg(https://segmentfault.com/img/remote/1460000011814572?w=680&h=383);上期 WebVR開(kāi)發(fā)教程——交互事件(一)頭顯與手柄 從頭顯和...
摘要:譯通過(guò)實(shí)例講解和防抖與節(jié)流源碼中推薦的文章,為了學(xué)習(xí)英語(yǔ),翻譯了一下原文鏈接作者本文來(lái)自一位倫敦前端工程師的技術(shù)投稿。首次或立即你可能發(fā)現(xiàn)防抖事件在等待觸發(fā)事件執(zhí)行,直到事件都結(jié)束后它才執(zhí)行。 [譯]通過(guò)實(shí)例講解Debouncing和Throtting(防抖與節(jié)流) lodash源碼中推薦的文章,為了學(xué)習(xí)(英語(yǔ)),翻譯了一下~ 原文鏈接 作者:DAVID CORBACHO 本文來(lái)自一位...
摘要:舉例舉例通過(guò)拖拽瀏覽器窗口,可以觸發(fā)很多次事件。不支持,所以不能在服務(wù)端用于文件系統(tǒng)事件??偨Y(jié)將一系列迅速觸發(fā)的事件例如敲擊鍵盤(pán)合并成一個(gè)單獨(dú)的事件。確保一個(gè)持續(xù)的操作流以每毫秒執(zhí)行一次的速度執(zhí)行。 Debounce 和 Throttle 是兩個(gè)很相似但是又不同的技術(shù),都可以控制一個(gè)函數(shù)在一段時(shí)間內(nèi)執(zhí)行的次數(shù)。 當(dāng)我們?cè)诓僮?DOM 事件的時(shí)候,為函數(shù)添加 debounce 或者 th...
摘要:把事件統(tǒng)一起來(lái)處理用戶的輸入要用到事件。就這樣,提取了鼠標(biāo)觸摸屏觸控筆的共通之處,以方便開(kāi)發(fā)跨設(shè)備的應(yīng)用。雖然是一個(gè)抽象,但它包含了鼠標(biāo)觸摸屏觸控筆的全部?jī)?nèi)容。手指與觸摸屏的屏幕接觸著,認(rèn)定為。 跨設(shè)備的問(wèn)題 平時(shí)我們?cè)陔娔X上訪問(wèn)的網(wǎng)頁(yè),大部分情況下是用鼠標(biāo)來(lái)控制的。比如說(shuō)鏈接跳轉(zhuǎn),就是鼠標(biāo)指針移動(dòng)到鏈接文字或圖片的位置,然后點(diǎn)擊一下。又比如說(shuō)滾動(dòng)屏幕,滑動(dòng)一下鼠標(biāo)滾輪就可以。 如果是...
摘要:把事件統(tǒng)一起來(lái)處理用戶的輸入要用到事件。就這樣,提取了鼠標(biāo)觸摸屏觸控筆的共通之處,以方便開(kāi)發(fā)跨設(shè)備的應(yīng)用。雖然是一個(gè)抽象,但它包含了鼠標(biāo)觸摸屏觸控筆的全部?jī)?nèi)容。手指與觸摸屏的屏幕接觸著,認(rèn)定為。 跨設(shè)備的問(wèn)題 平時(shí)我們?cè)陔娔X上訪問(wèn)的網(wǎng)頁(yè),大部分情況下是用鼠標(biāo)來(lái)控制的。比如說(shuō)鏈接跳轉(zhuǎn),就是鼠標(biāo)指針移動(dòng)到鏈接文字或圖片的位置,然后點(diǎn)擊一下。又比如說(shuō)滾動(dòng)屏幕,滑動(dòng)一下鼠標(biāo)滾輪就可以。 如果是...
閱讀 3197·2021-11-23 09:51
閱讀 1537·2021-11-22 09:34
閱讀 2846·2021-10-27 14:15
閱讀 2302·2021-10-12 10:17
閱讀 1900·2021-10-12 10:12
閱讀 963·2021-09-27 14:00
閱讀 2009·2021-09-22 15:19
閱讀 1042·2019-08-30 10:51