移動端click事件300ms延遲

2022-01-23 03:51:37 字數 3647 閱讀 6218

一般情況下,如果沒有經過特殊處理,移動端瀏覽器在派發點選事件的時候,通常會出現300ms左右的延遲。也就是說,當我們點選頁面的時候移動端瀏覽器並不是立即作出反應,而是會等上一小會兒才會出現點選的效果。在移動web興起的初期,使用者對300ms的延遲感覺不明顯。但是,隨著使用者對互動體驗的要求越來越高,現今,移動端300ms的點選延遲逐漸變得明顯而無法忍受。

那麼,移動端300ms的點選延遲是怎麼來的呢?

移動瀏覽器上支援的雙擊縮放操作,以及ios safari 上的雙擊滾動操作,是導致300ms的點選延遲主要原因。

預備知識:移動端點選乙個元素觸發事件的順序

以下是四種touch和click事件

touchstart: //手指放到螢幕上時觸發

touchmove: //手指在螢幕上滑動式觸發

touchend: //手指離開螢幕時觸發

touchcancel: //系統取消touch事件的時候觸發,這個好像比較少用

click://在這個dom(或冒泡到這個dom)上手指觸控開始,且手指未曾在螢幕上移動(某些瀏覽器允許移動乙個非常小的位移值),且在這個在這個dom上手指離開螢幕,且觸控和離開螢幕之間的間隔時間較短(某些瀏覽器不檢測間隔時間,也會觸發click)才能觸發

上述事件發生順序:在移動端,手指點選乙個元素,會經過:touchstart --> touchmove -> touchend --》click。

雙擊縮放:顧名思義,即用手指在螢幕上快速點選兩次,移動端瀏覽器會將網頁縮放至原始比例。 那麼這和 300 毫秒延遲有什麼聯絡呢? 假定這麼乙個場景。使用者在 瀏覽器裡邊點選了乙個鏈結。由於使用者可以進行雙擊縮放或者雙擊滾動的操作,當使用者一次點選螢幕之後,瀏覽器並不能立刻判斷使用者是確實要開啟這個鏈結,還是想要進行雙擊操作。因此,瀏覽器就等待 300 毫秒,以判斷使用者是否再次點選了螢幕。

也就是說,移動端瀏覽器會有一些預設的行為,比如雙擊縮放、雙擊滾動。這些行為,尤其是雙擊縮放,主要是為桌面**在移動端的瀏覽體驗設計的。而在使用者對頁面進行操作的時候,移動端瀏覽器會優先判斷使用者是否要觸發預設的行為。

對於不需要縮放的頁面,通過設定meta標籤禁用縮放,表明這個頁面是不需要縮放的,雙擊縮放就沒有意義了。此時瀏覽器可以禁用預設的雙擊縮放行為並且去掉300ms的點選延遲。

該方法缺點在於必須通過完全禁用縮放來達到去掉點選延遲的目的,但我們初衷是想禁止預設雙擊縮放行為,這樣就不用等待300ms來判斷當前操作是否是雙擊。但是通常情況下我們還是希望能通過雙指縮放來進行縮放操作,比如放大,很小的一段文字。

移動端瀏覽器缺省視口寬度一般比裝置瀏覽器視窗寬度大,通常是980px,我們可以通過如下標籤設定視口寬度為裝置寬度。

因為雙擊縮放主要是用來改善桌面站點在移動端瀏覽體驗的,而隨著響應式設計的普及,很多站點都已經對移動端坐過適配和優化了,這個時候就不需要雙擊縮放了,如果能夠識別出乙個**是響應式的**,那麼移動端瀏覽器就可以自動禁掉預設的雙擊縮放行為並且去掉300ms的點選延遲。chrome 32+中,如果設定了上述meta標籤,那瀏覽器就可以認為該**已經對移動端做過了適配和優化,就無需雙擊縮放操作了。

這個方案相比方案一的好處在於,它沒有完全禁用縮放,而只是禁用了瀏覽器預設的雙擊縮放行為,但使用者仍然可以通過雙指縮放操作來縮放頁面。不足在於其他瀏覽器的支援有限。

指標事件(point event)最初由微軟提出,現已進入 w3c 規範的候選推薦標準階段 (candidate recommendation)。指標事件是乙個新的 web 事件系列,相應的規範旨在使用乙個單獨的事件模型,對所有輸入型別,包括滑鼠 (mouse)、觸控 (touch)、觸控 (stylus) 等,進行統一的處理。

例如,你可以只去監聽乙個元素的 pointerdown事件,無需分別監聽其 touchstart和mousedown事件。其中有乙個和點選延遲直接相關的實現 —— 乙個名為 touch-action的新 css 屬性。根據規範,touch-action

屬性決定 「是否觸控操作會觸發使用者**的預設行為。這包括但不限於雙指縮放等行為」。

從實際應用的角度來看,touch-action決定了使用者在點選了目標元素之後,是否能夠進行雙指縮放或者雙擊縮放。因此,這也相當完美地解決了 300 毫秒點選延遲的問題。touch-action的默為 auto,將其置為 none 即可移除目標元素的 300 毫秒延遲。

目前而言,internet explorer 實現了指標事件,同時,現在已經有一些指標事件的 polyfills 可以在專案中使用了

指標事件的 polyfill 比較多,以下列出比較流行的幾個。

zepto 的touch模組中自定義了tap事件,用於代替click事件,表示乙個輕擊操作。touch模組實現tap的原理是繫結事件touchstart,touchmove和touchend到document上,然後通過計算touch事件觸發的時間差,位置差來實現了自定義的tap,swipe等。

zepto自定義的tap操作雖然可以解決300ms點選延遲問題,但存在著名的「點透」問題。不知其最新版本有沒有解決該問題。

***** fastclick 是 ft labs 專門為解決移動端瀏覽器 300 毫秒點選延遲問題所開發的乙個輕量級的庫。

通過sendclick模擬click事件:

fastclick.prototype.sendclick = function(targetelement, event) { // 這裡是一些狀態檢查邏輯

// 建立乙個滑鼠事件 clickevent = document.createevent('mouseevents'); // 初始化滑鼠事件為click事件 clickevent.initmouseevent(this.determineeventtype(targetelement), true, true, window, 1, touch.screenx, touch.screeny, touch.clientx, touch.clienty, false, false, false, false, 0, null); // fastclick的內部變數,用來識別click事件是原生還是模擬 clickevent.forwardedtouchevent = true; // 在目標元素上觸發該滑鼠事件, targetelement.dispatchevent(clickevent);

就目前而言,fastclick 非常實際地解決 300 毫秒點選延遲的問題。唯一的缺點可能也就是該指令碼的檔案尺寸 (儘管它只有 10kb)。

禁用縮放:簡單,但同時也使的網頁無法縮放,不適用於未對移動端瀏覽做適配優化的網頁。

更改缺省視口寬度:簡單,但需要瀏覽器支援。

指標事件和css touch-action:新屬性,可能存在瀏覽器相容問題,如僅為解決點選延遲問題兒引入一整套指標事件有點過了。

tap事件:能較好解決點選延遲,並且對其他移動端觸控事件也有較好支援,但存在點透問題,不知最新版是否解決。

fastclick:當前較好的專門解決點選延遲的庫,指令碼尺寸相對較大。

移動端300ms與點透總結

為啥會出現300ms延遲現象 下列情況不會出現300ms延遲 發生情況 a,b兩個層上下重疊在z軸中 繫結touchstart touchend事件,使上層的a點選後消失 b預設有click事件或b繫結了click事件 為什麼會產生點透 移動端事件執行順序 touchstart touchend c...

移動端300ms相容問題(移動端經典問題)

2007 年初。蘋果公司在發布首款 iphone 前夕,遇到乙個問題 當時的 都是為大螢幕裝置所設計的。於是蘋果的工程師們做了一些約定,應對 iphone 這種小螢幕瀏覽桌面端站點的問題。雙擊縮放 double tap to zoom 這也是會有上述 300 毫秒延遲的主要原因。雙擊縮放,即用手指在...

移動端click事件延時

在移動端使用click事件會產生300ms的延遲 問題的產生 移動端存在雙擊放大的問題,所以在移動端點選事件發生時,為了判斷使用者的行為 到底是要雙擊還是要點選 瀏覽器通常會等待300ms,如果300ms之內,使用者沒有再次點選,則判定為點選事件,否則判定為雙擊縮放。為什麼要解決 線代web對效能的...