移動端300ms延遲問題

1.300ms延遲由來

數約定,包括雙擊縮放,幾乎如今全部的移動端瀏覽器都有這個功能。  300 毫秒延遲的主要緣由是解決雙擊縮放(double tap to zoom)。雙擊縮放,顧名思義,即用手指在屏幕上快速點擊兩
次,iOS 自帶的 Safari 瀏覽器會將網頁縮放至原始比例。 那麼這和 300 毫秒延遲有什麼聯繫呢?
  假定這麼一個場景。用戶在 iOS Safari 裏邊點擊了一個連接。因爲用戶能夠進行雙擊縮放或者雙擊滾動的操做,當用
戶一次點擊屏幕以後,瀏覽器並不能馬上判斷用戶是確實要打開這個連接,仍是想要進行雙擊操做。所以,iOS Safari
就等待300毫秒,
以判斷用戶是否再次點擊了屏幕。鑑於iPhone的成功,其餘移動瀏覽器都複製了 iPhone Safari 瀏覽器的

 解決方案:fastclick庫或者使用touchstart事件代替點擊事件

2.fastclick 解決300ms延遲

   FastClick 是 FT labs 專門爲解決移動端瀏覽器 300ms 點擊延遲問題所開發的一個輕量級的庫。瀏覽器

    基本原理:FastClick 的實現原理是在檢測到 touchend 事件的時候,會經過 DOM 自定義事件當即出發模擬一個click事件,並把瀏覽器在 300ms 以後真正的 click 事件阻止掉。this

   fastClick的核心代碼spa

        FastClick.prototype.onTouchEnd = function (event) {
            // 一些狀態監測代碼  // 從這裏開始,
            if (!this.needsClick(targetElement)) {
                // 若是這不是一個須要使用原生click的元素,則屏蔽原生事件,避免觸發兩次click event.preventDefault();
                // 觸發一次模擬的click
                this.sendClick(targetElement, event);
            }
        }

   這裏能夠看到,FastClick 在 touchEnd 的時候,在符合條件的狀況下,主動觸發了click事件,這樣避免了瀏覽器默認的300ms 等待判斷。爲了防止原生的 click 被觸發,這裏還經過 event.preventDefault() 屏蔽了原生的click事件。prototype

   經過 sendClick 模擬 click 事件:code

        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 很是實際地解決 300ms 點擊延遲的問題。惟一的缺點可能也就是該腳本的文件尺寸 (儘管它只有 10kb)。blog

3.經過 touchstart 和 touchend 模擬實現

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

相關文章
相關標籤/搜索