近期項目中使用iScroll遇到一個問題,在設定wrapper爲橫向滾動時,若是你手指放在該區域,將沒法拉動頁面,也就是說該區域取消了默認事件。這個體驗是實在是沒法接受,特別是頁面中有多個橫向滾動區域時,很容易觸碰到這種區域,這時用戶將以爲頁面很卡。html
Google搜了一下,看來不少人都爲這個問題而煩惱。有高人給出瞭解決方案,在這裏能夠找到。app
代碼以下:測試
myScroll = new iScroll('scrollpanel', { // other options go here... vScroll: false, onBeforeScrollStart: function ( e ) { if ( this.absDistX > (this.absDistY + 5 ) ) { // user is scrolling the x axis, so prevent the browsers' native scrolling e.preventDefault(); } } });
重寫onBeforeScrollStart事件,判斷touch的滑動距離,只在橫向滑動距離大於豎向滑動距離時(也就是左右滑動時)才取消默認事件,這樣就不影響頁面滾動了。看iScroll源碼,onBeforeScrollStart: function (e) { e.preventDefault(); }, 它默認是直接取消默認事件。this
到這裏的時候感受就不錯了。可是不要高興的太早。spa
上下滑動橫向滾動區域,頁面確實能夠滾動了,但在多體驗了幾回頁面以後,又出現了一個問題。code
先左右滑動該區域,滾動中止後再按住該區域想滾動頁面,你會發現它仍是不能滾動頁面,這時你再點擊一次該區域,這時能夠了。這相對於你須要觸摸2次才能滾動頁面, 這樣的行爲仍是讓人沒法接受。htm
通過多翻測試,我把問題鎖定到absDistX/Y上。最後發現,在左右滑動以後absDistX/Y的值不會重置,第二次滑動該區域時執行onBeforeScrollStart事件,裏面absDistX/Y值是上一次的值,因此程序仍是阻止了頁面滾動。blog
解決方法以下:事件
myScroll = new iScroll('scrollpanel', { // other options go here... hScroll: true, onBeforeScrollStart: function ( e ) { if ( this.absDistX > (this.absDistY + 5 ) ) { // user is scrolling the x axis, so prevent the browsers' native scrolling e.preventDefault(); } }, //解決第一次沒法滑動的問題 onTouchEnd: function () { var self = this; if (self.touchEndTimeId) { clearTimeout(self.touchEndTimeId); } self.touchEndTimeId = setTimeout(function () { self.absDistX = 0; self.absDistY = 0; }, 600); } });
在onTouchEnd裏面作處理,每次滑動以後都重置absDistX/Y的值。爲何要使用setTimeout?實際上是爲了防止誤判斷,太敏感也很差,有時候你只是想左右滑動雖然滑動的角度有點朝上或朝下。get
Ok,如今終於爽了,想怎麼滑都行。