頭幾天官網剛上線,就接到投訴說有問題。過去一看,我靠什麼鬼?!Mac下用觸控板一滑到底,——首頁上用iscroll寫的翻頁效果直接全軍覆沒。javascript
這個bug來的莫名其妙,問了一圈人也沒什麼思路,後來本身上網搜,在一個頁面上找到一段關於Mac的觸控板的手勢滑動會瘋狂觸發滾輪事件的記錄,可是輪到具體的解決方案就語焉不詳了。沒轍,靠天沒用,仍是靠本身吧~java
這裏先簡單介紹下。出問題的首頁用的是iscroll插件,用snap
屬性作的整屏翻頁的效果,翻頁用鼠標滾輪驅動,這塊用的是MDN上的一個滾輪事件的兼容代碼,回調使用iscroll的接口完成向上/向下翻頁的效果。git
回到這個問題上。一開始我想用事件防抖解決,因而用setTimeout()
本身寫了個:觸發事件後先進入延時,延時後執行函數;若是在延時內仍有事件觸發,則取消原有的延時從新計時。瀏覽器
// 打底用的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);
我本意是用延時抵消掉重複觸發的滾輪事件,最後合成一個事件觸發,沒想到測試以後,Mac上的問題並無解決。ide
因而我想,用事件防抖的思路處理應該仍是不對,即使是延遲時間較短,若是事件持續觸發的話確定翻頁仍是會被無限的延遲阻塞掉,至此我想換用事件節流再試試。在找資料的時候,意外發現了Underscore.js這個工具庫,裏邊不只有現成的節流和防抖(中文文檔裏用的是「防反跳」)函數能夠用,並且還支持鏈式調用,而且壓縮版本也才十幾k,正合我意。函數
說幹就幹,立刻用Underscore擼了個事件節流版的:工具
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);//這裏毫秒數用了400,大概至關於一個短動畫的執行時間 addWheelListener($('body')[0], wheelSlide);
鏈式寫法看上去還挺不錯的!進本機瀏覽器(PC)……嗯?爲啥最後會跳一下?趕忙翻文檔,又加了個參數上去:測試
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也從一滑到底變成了有「段落感」的跳動,但結果仍是不對……
一狠心把毫秒數改爲了5000,結果呢:還、是、不、對、、、。。。
(//陷入循環懵逼狀態ing……)
痛定思痛,必定是文檔看的不夠多!因而又啃了一遍Underscore.js的文檔(雖然是翻譯的,囧……),發現防抖竟然有個[immediate]
參數,是能夠優先執行的!大喜過望~接着擼:動畫
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);// 原本想改回400的,有點心虛因此又加了200…… addWheelListener($('body')[0], wheelSlide);
竟然PC和Mac都能一頁頁的翻頁了有!沒!有!不過翻頁的動做還有點遲滯,因而果斷把毫秒數改小: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);
總結:
Mac觸控板bug踩坑 +1;
理解了事件節流和事件防抖的概念;
Underscore.js真好用;
感謝git把每次的修改都記了下來。