mobile terminals touch event problems

這兩天自己在寫一個手機網頁,用到了觸屏滑動的特效,就是往右滑動的時候左側隱藏的菜單從左邊劃出來。
做完之後在手機原生瀏覽器中運行正常,但在QQ和微信中打開,發現touchmove只會觸發一次,而且touchend也經常不觸發。
之後百度了一下這個問題,原因是

主要是由於200ms超時導致內核不一定會一直處理touchmove事件,一旦超時會將後續所有的事件轉交給UI處理,導致touchmove不會一直觸發。爲了解決開發者需要,建議開發者在touchstart時調用event.preventDefault,這樣就可以保證內核會一起觸發touchmove事件了。

根據上面所說,在touchstart中添加了event.preventDefault()方法,在QQ和微信中果然正常了。
但是!!!頁面中的超鏈接點擊沒反應了!!!給其他地方加的click事件也不觸發了!!!
之後繼續百度,得知當在移動端上點擊屏幕時,會依次觸發touchstart,touchmove,touchend,click事件。
之後測試了一下,發現正確的觸發過程應該是:touchstart→touchmove→touchend或者touchstart→touchend→click。
如果在點擊屏幕的時候手指滑動的話,是不會觸發click事件的。
上面說event.preventDefault()的方法,會阻止事件的默認行爲。可以通過調用preventDefault()方法,可以阻止後面事件的觸發。
我知道event.preventDefault()會阻止a標籤默認的動作(跳轉到href指定的頁面),但是爲什麼click也不觸發了呢?
之後我大膽推測了一下:
會不會是因爲在移動端click事件的觸發條件就是必須touchstart和touchend同時觸發才能觸發click呢?
我在touchstart中調用了event.preventDefault方法,是不是讓瀏覽器誤以爲沒有觸發touchstart事件,只觸發了touchend事件,所以沒有觸發click事件呢?
之後我刪除了touchstart中的event.preventDefault方法,果然超鏈接和click事件都觸發了,但是前面說的問題又出現了,在QQ和微信中touchmove和touchend又出問題了。
怎麼辦呢?
後來突然腦袋靈光一閃,既然在touchstart中加了event.preventDefault會導致不觸發click事件,那我在touchmove中加可以吧?
抱着試一試的心態,果然好了,click能順利觸發,QQ和微信中也沒有問題,我以爲這樣就好了,但是爲什麼頁面不能滾動了?
原來touchmove中添加event.preventDefault方法之後會阻止瀏覽器默認的滾動。。。
所以頁面無法滾動了,之後又去找找找,找了很久一直沒找到怎麼解決這個問題,突然想起之後用的一個移動端的圖片輪播插件,
爲什麼他們可以左右滑動,不影響click事件和a標籤,也不影響頁面的滾動。
然後我打開了這個插件的源碼,終於在touchmove中找到了答案
在touchmove中有這樣一段代碼(下面是我自己抄過來簡化過的):

var w = x<0?x*-1:x;     //x軸的滑動值
var h = y<0?y*-1:y;     //y軸的滑動值
if(w>h){                //如果是在x軸中滑動
   event.preventDefault();
}

就是在touchmove中判斷x軸和y軸的移動值,判斷當前是往哪個方向滑動,如果是在x軸上滑動(左右),就調用event.preventDefault()方法,如果是在y軸上滑動(上下),就不調用event.preventDefault()。

然後測試一下,QQ和微信中特效沒有問題,click事件和a標籤鏈接也可以順利觸發,頁面滾動也沒有問題。
所有問題終於解決了。。

總結一下:
在QQ和微信(當然還包括其他瀏覽器,不過我沒測試過)中如果有需要用到touch事件做的特效一定要在touchstart或者touchmove中添加event.preventDefault()方法。
在touchstart中如果有event.preventDefault()方法, 將不會觸發click事件和a標籤方法。在這裏可以使用tap代替click,但是a標籤的話就不太方便了。
如果在touchmove中有event.preventDefault()方法,最好加上方向判斷,當然如果你頁面內容不需要滾動條就不需要加判斷了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章