天天看點

Zepto tap事件中需要觸發兩次的問題

最近在使用

zepto.js

的時候,發現其

tap

事件的一個BUG,被産品和測試同學反複找了幾次之後,終于下定決定去研究

zepto

的源碼,并解決了問題。

BUG情況說明:

給頁面

<a>

标簽綁定了

tap

事件,在移動裝置上點選按鈕貌似一切正常,可以正常響應。

但是,把頁面上下滑動幾次之後,或者在滑動時手指滑動出移動螢幕之外,之後再點選按鈕,就會發現第一次點選的時候事件沒被觸發,需要點選第二次才會正常,而且幾乎是必現的。一開始的時候我還以為是安卓Webview要擷取頁面焦點的原因,後來研究了下

zepto

源碼之後,發現原來不是。

Tap事件實作原理:

其實不用看代碼都猜的出來,是用

touchstart

touchmove

touchend

這三個事件去實作的,沒錯,就是這樣。

但是為了區分“點選”和“拖動”兩個動作,

zepto

是用了

deltaX

deltaY

兩個變量去分别記錄手指在觸碰到螢幕時到離開螢幕時的x軸和y軸距離,如果

deltaX>30px

或者

deltaY>30px

,則認為是“拖動”動作,就不會觸發

tap

事件了。

一切看似正常,但是細看一下,原來

deltaX

deltaY

的置0的是在

touchend

裡實作的,而移動裝置上,有兩種情況是有可能導緻

touchend

事件沒觸發(1.快速劃動螢幕多次,2.劃動螢幕時手指劃出螢幕邊界),這樣

deltaX

deltaY

就不會被置0了,等到下次再點選的時候,

deltaX

deltaY

就有可能大于

30px

,導緻

tap

事件不被觸發。

問題解決:

想必大家都知道該怎麼解決,沒錯,就是在

touchstart

時添加

deltaX

deltaY

的置0,代碼如下:

.on('touchstart MSPointerDown pointerdown', function(e){  
    deltaX = deltaY = ;  
    ...... 
           

修改位置:zepto裡或者touch.js裡修改。

繼續閱讀