天天看點

設計方案--移動端延遲300ms的原因以及解決方案

一、前言

移動端浏覽器提供一個特殊的功能:輕按兩下(double tap)縮放。

二、移動端延遲300ms的原因

為什麼要用觸摸事件?觸摸事件是移動端浏覽器特有的html5事件。

因為移動端的click有很大延遲(大約300ms),300ms延遲來自判斷輕按兩下和長按,因為隻有預設等待時間結束以确定沒有後續動作發生時,才會觸發click事件。而觸摸事件的延遲則是非常短的,使用觸摸事件的能夠提高頁面響應速度,帶來更好的使用者體驗。

重點:由于移動端會有輕按兩下縮放的這個操作,是以浏覽器在click之後要等待300ms,看使用者有沒有下一次點選,也就是這次操作是不是輕按兩下。

五、點選穿透問題

說完移動端點選300ms延遲的問題,還不得不提一下移動端點選穿透的問題。既然click點選有300ms的延遲,那對于觸摸屏,我們直接監聽touchstart事件不就好了嗎?

使用touchstart去代替click事件有兩個不好的地方。

第一:touchstart是手指觸摸螢幕就觸發,有時候使用者隻是想滑動螢幕,卻觸發了touchstart事件,這不是我們想要的結果;

第二:使用touchstart事件在某些場景下可能會出現點選穿透的現象。

1、什麼是點選穿透?

假如頁面上有兩個元素A和B。B元素在A元素之上。我們在B元素的touchstart事件上注冊了一個回調函數,該回調函數的作用是隐藏B元素。我們發現,當我們點選B元素,B元素被隐藏了,随後,A元素觸發了click事件。

這是因為在移動端浏覽器,事件執行的順序是touchstart > touchend > click。而click事件有300ms的延遲,當touchstart事件把B元素隐藏之後,隔了300ms,浏覽器觸發了click事件,但是此時B元素不見了,是以該事件被派發到了A元素身上。如果A元素是一個連結,那此時頁面就會意外地跳轉。

詳細方案:

(1)隻用touch

最簡單的解決方案,完美解決點選穿透問題。

把頁面内所有click全部換成touch事件 <code>touchstart</code> 、’touchend’、’tap’, 需要特别注意 a标簽,a标簽的href也是click,需要去掉換成js控制的跳轉,或者直接改成span + tap控制跳轉。

(2)隻用click

下下策 ,因為會帶來300ms延遲,頁面内任何一個自定義互動都将增加300毫秒延遲,想想都慢。不用touch就不會存在touch之後300ms觸發click的問題。

(3)拿個東西擋住

比較笨的方法, 千萬不要用。

(4)tap後延遲350ms再隐藏mask

改動最小,缺點是隐藏mask變慢了,350ms還是能感覺到慢的。

(5)pointer-events

比較麻煩且有缺陷, 不建議使用。mask隐藏後,給按鈕下面元素添上 pointer-events: none; 樣式,讓click穿過去,350ms後去掉這個樣式,恢複響應。缺陷是mask消失後的的350ms内,使用者可以看到按鈕下面的元素點着沒反應,如果使用者手速很快的話一定會發現。

(6)在下面元素的事件處理器裡做檢測(配合全局flag)

比較麻煩, 不建議使用。全局flag記錄按鈕點選的位置(坐标點),在下面元素的事件處理器裡判斷event的坐标點,如果相同則是那個可惡的click,拒絕響應。

繼續閱讀