1. 程式人生 > 實用技巧 >移動端300ms延遲

移動端300ms延遲

1. 300ms延遲的產生緣由

移動端瀏覽器的預設顯示寬度是980px(不同機型各異,但相差不大),而不是螢幕的寬度(320px或其他)。為了對早期普通網頁更好的體驗,iphone設計了雙擊放大顯示的功能--這就是300ms延遲的來源:如果使用者一次點選後300ms內沒有其他操作,則認為是個單擊行為;否則為雙擊放大行為。

2. 點透行為

假設有兩個層級,ABA在上面,B在下面。 如果A監聽touch事件(zeptotap事件),而且B上有個連結(或者監聽click事件),那麼當touch A後,先後觸發了touchStarttouchEnd事件,touchEndA層隱藏,而此刻會觸發在document

最前面Bclick事件;這就是點透行為。

3. 解決方法

  1. 設定不能縮放:user-scalable=no。 不能縮放就不會有雙擊縮放操作,因此click事件也就沒了300ms延遲,這個是Chrome首先在Android中提出的。
  2. 設定顯示寬度:width=device-widthChrome 開發團隊不久前宣佈,在 Chrome 32 這一版中,他們將在包含 width=device-width 或者置為比 viewport 值更小的頁面上禁用雙擊縮放。當然,沒有雙擊縮放就沒有 300 毫秒點選延遲。
  3. IE的指標事件 (Pointer Events):設定touch-action:none,根據
    規範
    touch-action 屬性決定 “是否觸控操作會觸發使用者代理的預設行為。這包括但不限於雙指縮放等行為”
    從實際應用的角度來看,touch-action決定了使用者在點選了目標元素之後,是否能夠進行雙指縮放或者雙擊縮放。因此,這也相當完美地解決了 300 毫秒點選延遲的問題。

鑑於上述的3種解決方案,現在較為通用的meta設定為:

<meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no">

4. 現在的流行解決方案:

上述的3種解決方案可以解決Chrome AndroidIE10+下的300ms問題,但是對其他瀏覽器還需要特定的解決方案。

  1. 指標事件的 polyfill
    指標事件的 polyfill 比較多,以下列出比較流行的幾個。GooglePolymer,微軟的 HandJS@Rich-HarrisPoints
  2. FastClick
    FastClickFT Labs 專門為解決移動端瀏覽器 300 毫秒點選延遲問題所開發的一個輕量級的庫。簡而言之,FastClick 在檢測到 touchend事件的時候,會通過 DOM 自定義事件立即觸發一個模擬click事件,並把瀏覽器在 300 毫秒之後真正觸發的 click事件阻止掉。

5. FastClick

現階段FastClick被更多使用,藉助它通過監聽click事件,即可消除300ms的問題。
通過閱讀原始碼可知:

  1. FastClick通過判斷瀏覽器型別決定其是不是需要執行,下面幾種場景下不會執行FastClick邏輯:
  • 不支援ontouchstart事件的瀏覽器
  • Android Chrome 或者 firefox27以上 設定了user-scalable="no"
  • 滿足特定要求的 IE10+ 瀏覽器
  • 部分黑莓瀏覽器
  1. 註冊了touchStarttouchEnd等事件,監聽touchStart決定事件物件的target、時間、位置等資訊;通過touchEnd得到touch的結束時間。如果touch時長大於700ms,則是長按事件;如果連續兩次touchEnd的時間間隔小於200ms,那麼認定為快速點選,特殊對待;排除上面兩種情況,就通過clickEvent = document.createEvent('MouseEvents'); initMouseEvent; dispatchEvent手動觸發click事件。