【移動端】移動端點擊300ms延遲原因及解決方案


移動端300ms延遲原因

2007 年初。蘋果公司在發布首款 iPhone 前夕,遇到一個問題:當時的網站都是為大屏幕設備所設計的。於是蘋果的工程師們做了一些約定,應對 iPhone 這種小屏幕瀏覽桌面端站點的問題。

雙擊縮放(double tap to zoom),這也是會有上述 300 毫秒延遲的主要原因。雙擊縮放,即用手指在屏幕上快速點擊兩次,iOS 自帶的 Safari 瀏覽器會將網頁縮放至原始比例。

假定這么一個場景。用戶在 iOS Safari 里邊點擊了一個鏈接。由於用戶可以進行雙擊縮放或者單擊跳轉的操作,當用戶一次點擊屏幕之后,瀏覽器並不能立刻判斷用戶是確實要打開這個鏈接,還是想要進行雙擊操作。因此,iOS Safari 就等待 300 毫秒,以判斷用戶是否再次點擊了屏幕。

鑒於iPhone的成功,其他移動瀏覽器都復制了 iPhone Safari 瀏覽器的多數約定,包括雙擊縮放,幾乎現在所有的移動端瀏覽器都有這個功能。

解決方案

1. faskclick https://github.com/ftlabs/fastclick

  • 原理: 在檢測到touchend事件的時候,會通過DOM自定義事件立即出發模擬一個click事件,並把瀏覽器在300ms之后真正的click事件阻止掉
  • 缺點: 腳本相對較大, 不建議使用

2. 禁用游覽器縮放

當HTML文檔頭部包含如下meta標簽時:

<meta name="viewport" content="user-scalable=no">
<meta name="viewport" content="initial-scale=1, maximum-scale=1">
表明這個頁面是不可縮放的,那雙擊縮放的功能就沒有意義了,此時瀏覽器可以禁用默認的雙擊縮放行為並且去掉300ms的點擊延遲。
這個方案有一個缺點,就是必須通過完全禁用縮放來達到去掉點擊延遲的目的,然而完全禁用縮放並不是我們的初衷,我們只是想禁掉默認的雙擊縮放行為,這樣就不用等待300ms來判斷當前操作是否是雙擊。但是通常情況下,我們還是希望頁面能通過雙指縮放來進行縮放操作,比如放大一張圖片,放大一段很小的文字。

3. 更改默認的視口寬度

<meta name="viewport" content="width=device-width">
一開始,因為雙擊縮放主要是用來改善桌面站點在移動端瀏覽體驗的。 隨着發展現在都是專門為移動開發專門的站點,這個時候就不需要雙擊縮放了,所以移動端瀏覽器就可以自動禁掉默認的雙擊縮放行為並且去掉300ms的點擊延遲。如果設置了上述meta標簽,那瀏覽器就可以認為該網站已經對移動端做過了適配和優化,就無需雙擊縮放操作了。
這個方案相比方案一的好處在於,它沒有完全禁用縮放,而只是禁用了瀏覽器默認的雙擊縮放行為,但用戶仍然可以通過雙指縮放操作來縮放頁面。

4.通過 touchstart 和 touchend模擬實現

能不能直接用 touchstart代替click呢,
答案是不能,使用touchstart去代替click事件有兩個不好的地方。
第一:touchstart是手指觸摸屏幕就觸發,有時候用戶只是想滑動屏幕,卻觸發了touchstart事件,這不是我們想要的結果;
第二:使用touchstart事件在某些場景下可能會出現點擊穿透的現象。

什么是點擊穿透?

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

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

5.touch-action

CSS3 新屬性, touch-action: manipulation;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM