快速反饋對於任何 UI 的實現都是至關重要的。研究表明,100ms 是界面讓用戶感到即時的最大延遲。儘管如此,移動網路仍然受到一個巨大的反饋問題的困擾:觸摸任何元素後,延遲 300 毫秒。這種延遲是許多用戶認為基於 HTML 的 Web 應用程式“卡頓”的最重要原因之一。在本文中,本文將帶你瞭解移動... ...
快速反饋對於任何 UI 的實現都是至關重要的。研究表明,100ms 是界面讓用戶感到即時的最大延遲。儘管如此,移動網路仍然受到一個巨大的反饋問題的困擾:觸摸任何元素後,延遲 300 毫秒。這種延遲是許多用戶認為基於 HTML 的 Web 應用程式“卡頓”的最重要原因之一。在本文中,本文將帶你瞭解移動端點擊事件延遲的從誕生到消亡的過程。
誕生史
在 2007 年,蘋果公司發佈首款 iPhone 之前,由於當時的網站普遍為大屏幕設備所設計,為了應對 iPhone 這種小屏幕設備瀏覽桌面網站的問題,由此,蘋果引入了多項變革,其中就包含了“雙擊縮放準確定位正文主體,並將其縮放至適合的比例展現”的功能,即雙擊縮放功能。然而,由於這種雙擊縮放的操作,在用戶第一次單擊頁面元素時,瀏覽器並不知道用戶是想做雙擊縮放操作還是普通的單擊操作。因此,IOS Safari 瀏覽器首先引入了 300 毫秒延遲,用來判斷用戶是否會再次點擊,也就是說,在第一次點擊延遲 300 毫秒,300 毫秒後用戶沒有再次點擊則認定為用戶在進行普通的單擊操作,並觸發單擊(Click)事件。
全面的移動開發者與單擊事件延遲戰爭拉開了序幕。鑒於 iPhone 的巨大成功,其他瀏覽器廠商也都快步跟進紛紛效仿了 iPhone Safari 瀏覽器的做法。於是,單擊事件延遲成為了移動開發者不得不面對的痛。
消亡史
雖然從當時來看 300ms 延遲並沒有什麼不妥,然而在越來越註重用戶體驗的移動互聯網時代,這種延遲是無法被用戶所接受的,加之開發者也可以對網站進行響應式適配,雙擊縮放的操作變成了一種可有可無的操作,瀏覽器廠商開始意識到延遲所帶來的體驗問題,提出了一些解決方案。
禁用縮放
解決此問題的第一個方法是常識性方法。由於延遲產生的原因是雙擊縮放操作,那麼就禁用頁面縮放功能,最直接的方法就是設置 Viewport 禁止縮放,代碼如下:
<meta name="viewport" content="user-scalable=no">
<!-- 或者 -->
<meta name="viewport" content="initial-scale=1,maximum-scale=1">
適用於 Android 的 Chrome 瀏覽器是第一個引入此更改的應用程式,隨後緊接著是 Android 的 Firefox。沒有其他瀏覽器供應商宣佈要添加此優化的計劃。儘管此解決方案非常巧妙,背後卻以犧牲整個頁面縮放為代價,帶來的影響是對於頁面上的圖像或小文本,想要進行縮放變得難以完成。即大多數網站都無法從 Android 版 Chrome 和 Android 版 Firefox 的優化中受益。
幸運的是,隨後 Chrome 團隊在 Chrome 32 之後的版本中,提出了新的優秀方案,代碼如下:
<meta name="viewport" content="width=device-width">
約定當 Viewport 的 width 小於或等於 device-width 時,去除雙擊縮放功能。這項技術的另一個關鍵在於,它僅消除了雙擊縮放的功能,用戶依然可以使用雙指縮放功能。因此,不存在與禁用縮放相關的可用性和可訪問性問題。
指針事件
指針事件是 Microsoft 提出的一系列針對 Web 的新事件,現已成為 W3C 規範。指針事件規範是嘗試使用單個事件模型統一我們對所有輸入類型(滑鼠,觸摸,手寫筆等)的處理。根據規範,CSS 屬性 touch-action 用於設置觸摸屏用戶如何操縱元素的區域(例如,瀏覽器內置的縮放功能)。touch-action 預設值是 auto,當設置為 none 時會禁止用戶縮放,能成功解決 300ms 延遲的問題,如:
a[href],
button {
touch-action: none;
}
甚至可以添加 touch-action: none 到 body 以完全禁用雙擊來縮放(註意:這也將禁用雙指縮放功能,因此它與我們前面討論的與禁用縮放相關的可訪問性和可用性問題相同)。
2014年3月13日,W3C 規範增添了新的 touch-action 屬性值 manipulation。該屬性值提供了兩全其美的體驗;它允許雙指縮放,以避免 touch-action: none 出現的可訪問性和可用性問題,但它仍然可以通過禁用雙擊縮放來消除 300ms 的延遲。
FastClick
FastClick 是一個小型 JavaScript 庫,專門旨在防止移動瀏覽器中的 300ms 點擊延遲。FastClick 的實現基礎建立於 touchstart ,touchmove 或者 touchend 事件中的任意一個調用 event.preventDefault,mouse 事件 以及 click 事件將不會觸發。FastClick 的原理在 touchend 階段調用 event.preventDefault,然後通過 document.createEvent 創建一個自定義事件 MouseEvents,然後通過 eventTarget.dispatchEvent 觸發對應目標元素上綁定的 click 事件。
關於 FastClick 的好處是,它非常容易使用,只需在文檔載入後調用 FastClick.attach() 在 body 元素上實例化:
if ('addEventListener' in document) {
document.addEventListener('DOMContentLoaded', function() {
FastClick.attach(document.body);
}, false);
}
FastClick足夠聰明,可以檢測到如果是桌面瀏覽器或者存在 meta 標記和 touch-action 解決方案的時候,不會執行任何操作。因此,在我們為所有平臺提供真正的解決方案之前,這是一個極好的解決方法。
現代瀏覽器
得益於現代瀏覽器對 W3C 規範 touch-action: manipulation 的支持性,才真正徹底解決了點擊事件延遲的問題。touch-action: manipulation 規定瀏覽器只允許進行滾動和持續縮放操作。任何其它被 touch-action: auto 支持的行為不被支持。啟用平移和雙指縮放手勢,但禁用其他非標準手勢,例如雙擊縮放。 禁用雙擊縮放功能可減少瀏覽器在用戶點擊屏幕時延遲生成點擊事件的需要。代碼如下:
html {
touch-action: manipulation;
}
從此,移動端點擊事件延遲正式宣告消亡。