fastclick 解决移动端click事件300ms延迟
移動端click 事件延遲300ms
一般情況下,如果沒有經過特殊處理,移動端瀏覽器在派發點擊事件的時候,通常會出現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,我們可以通過如下標簽設置視口寬度為設備寬度。
<pre><code><meta name="viewport" content="width=device-width"></code></pre>因為雙擊縮放主要是用來改善桌面站點在移動端瀏覽體驗的,而隨著響應式設計的普及,很多站點都已經對移動端坐過適配和優化了,這個時候就不需要雙擊縮放了,如果能夠識別出一個網站是響應式的網站,那么移動端瀏覽器就可以自動禁掉默認的雙擊縮放行為并且去掉300ms的點擊延遲。chrome 32+中,如果設置了上述meta標簽,那瀏覽器就可以認為該網站已經對移動端做過了適配和優化,就無需雙擊縮放操作了。
這個方案相比方案一的好處在于,它沒有完全禁用縮放,而只是禁用了瀏覽器默認的雙擊縮放行為,但用戶仍然可以通過雙指縮放操作來縮放頁面。不足在于其他瀏覽器的支持有限。
css touch-action
指針事件(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
指針事件的 polyfill 比較多,以下列出比較流行的幾個。
Google 的 Polymer
微軟的 HandJS
@Rich-Harris 的 Points
為避免 300 毫秒點擊延遲,我們主要關心這些 polyfill 是如何在非 IE 瀏覽器中模擬 CSS touch-action屬性的,這其實是一個不小的挑戰。由于瀏覽器會忽略不被支持的 CSS 屬性,唯一能夠檢測開發者是否聲明了 touch-action: none的方法是使用 JavaScript 去請求并解析所有的樣式表。HandJS 也正是這么做的,但不管是從性能上來看還是其他一些復雜的方面,這都會遇到問題。
Polymer 則是通過判斷標簽上的 touch-action屬性 (attribute),而非 CSS 代碼。
這對于我們開發者來說意味著什么?如果你比較感興趣,想深入指針事件,那上述 polyfill 就非常適合應用到手頭的項目中。然而,你若只想尋求一個解決 300 毫秒點擊延遲的方法,上述方案可能就有點過了,因為它們要么是資源密集型的方案,要么是touch-action屬性的非標準化模擬。所以,接下去我們要來看一些專門針對 300 毫秒延遲而生的解決方案
zepto等庫的 tap事件
zepto 的touch模塊中自定義了tap事件,用于代替click事件,表示一個輕擊操作。touch模塊實現tap的原理是綁定事件touchstart,touchmove和touchend到document上,然后通過計算touch事件觸發的時間差,位置差來實現了自定義的tap,swipe等。
zepto自定義的tap操作雖然可以解決300ms點擊延遲問題,但存在著名的“點透”問題。不知其最新版本有沒有解決該問題。
fastclick 解決300ms延遲。
***** FastClick 是 FT Labs 專門為解決移動端瀏覽器 300 毫秒點擊延遲問題所開發的一個輕量級的庫。
基本原理:FastClick的實現原理是在檢測到touchend事件的時候,會通過DOM自定義事件立即出發模擬一個click事件,并把瀏覽器在300ms之后真正的click事件阻止掉。
fastClick的核心代碼
這里可以看到,FastClick在touchEnd的時候,在符合條件的情況下,主動觸發了click事件,這樣避免了瀏覽器默認的300毫秒等待判斷。為了防止原生的click被觸發,這里還通過event.preventDefault()屏蔽了原生的click事件。
通過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:當前較好的專門解決點擊延遲的庫,腳本尺寸相對較大。
作者:liusihowe
鏈接:https://www.jianshu.com/p/16d3e4f9b2a9
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權并注明出處。
總結
以上是生活随笔為你收集整理的fastclick 解决移动端click事件300ms延迟的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SQL2014数据导入到SQL2008R
- 下一篇: 计算机音乐制作专业艺考,西安音乐学院20