數約定,包括雙擊縮放,幾乎如今全部的移動端瀏覽器都有這個功能。 300 毫秒延遲的主要緣由是解決雙擊縮放(double tap to zoom)。雙擊縮放,顧名思義,即用手指在屏幕上快速點擊兩
次,iOS 自帶的 Safari 瀏覽器會將網頁縮放至原始比例。 那麼這和 300 毫秒延遲有什麼聯繫呢?
假定這麼一個場景。用戶在 iOS Safari 裏邊點擊了一個連接。因爲用戶能夠進行雙擊縮放或者雙擊滾動的操做,當用
戶一次點擊屏幕以後,瀏覽器並不能馬上判斷用戶是確實要打開這個連接,仍是想要進行雙擊操做。所以,iOS Safari就等待300毫秒,
以判斷用戶是否再次點擊了屏幕。鑑於iPhone的成功,其餘移動瀏覽器都複製了 iPhone Safari 瀏覽器的
解決方案:fastclick庫或者使用touchstart事件代替點擊事件
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
能不能直接用 touchstart 代替click呢,
答案是不能,使用 touchstart 去代替click事件有兩個很差的地方。
第一:touchstart 是手指觸摸屏幕就觸發,有時候用戶只是想滑動屏幕,卻觸發了 touchstart 事件,這不是咱們想要的結果;
第二:使用 touchstart 事件在某些場景下可能會出現點擊穿透的現象。事件