端點(diǎn)擊延遲消除方案:300ms 延遲原理、接入方式與源碼實(shí)現(xiàn)解析)
前端移動(dòng)開發(fā)【免費(fèi)下載鏈接】fastclickPolyfill to remove click delays on browsers with touch UIs項(xiàng)目地址https://gitcode.com/gh_mirrors/fa/fastclick點(diǎn)擊查看免費(fèi)下載FastClick 是一個(gè)輕量級(jí)的前端 Polyfill用于消除移動(dòng)瀏覽器中物理點(diǎn)擊tap到 click 事件觸發(fā)之間約 300ms 的延遲讓 Web 應(yīng)用在觸屏設(shè)備上獲得更接近原生的即時(shí)響應(yīng)。本文以 README.md 為主線結(jié)合 lib/fastclick.js 源碼、Makefile 構(gòu)建腳本與 examples/ 示例系統(tǒng)講解 FastClick 的延遲成因、兼容性邊界、五種接入方式、needsclick高級(jí)用法及底層實(shí)現(xiàn)原理幫助你在引入或維護(hù)該庫(kù)時(shí)快速掌握完整的技術(shù)細(xì)節(jié)。為什么存在 300ms 延遲移動(dòng)瀏覽器在用戶點(diǎn)擊tap按鈕之后并不會(huì)立即觸發(fā)click事件而是會(huì)等待約 300ms。原因正如 Google 在 fast buttons 相關(guān)文檔中說明的瀏覽器需要等待這段時(shí)間來判斷用戶是否正在進(jìn)行雙擊double tap操作——如果立即觸發(fā)click就無法區(qū)分單擊與雙擊縮放手勢(shì)。這 300ms 的等待時(shí)間會(huì)讓頁面交互產(chǎn)生明顯的滯后感。FastClick 的目標(biāo)就是在不干擾現(xiàn)有業(yè)務(wù)邏輯的前提下讓觸屏上的點(diǎn)擊響應(yīng)盡可能即時(shí)提升應(yīng)用的操作流暢度。需要特別留意截至 2015 年底大多數(shù)移動(dòng)瀏覽器尤其是 Chrome 和 Safari已經(jīng)不再存在 300ms 觸摸延遲因此 FastClick 在新版瀏覽器上不再帶來收益反而可能引入 bugs。是否使用 FastClick請(qǐng)結(jié)合你的目標(biāo)用戶群體與瀏覽器環(huán)境慎重決策。FastClick 如何工作源碼級(jí)原理FastClick 由 FT LabsFinancial Times 旗下實(shí)驗(yàn)室開發(fā)核心實(shí)現(xiàn)位于 lib/fastclick.js通過監(jiān)聽 touch 事件并在touchend觸發(fā)的第一時(shí)間合成synthesise并派發(fā)一個(gè) click 事件同時(shí)抑制瀏覽器隨后產(chǎn)生的原生 click從而把點(diǎn)擊事件提前到觸摸結(jié)束時(shí)立刻觸發(fā)。監(jiān)聽的事件與調(diào)用鏈FastClick(layer, options)構(gòu)造函數(shù)會(huì)在指定的 layer 上注冊(cè)以下事件監(jiān)聽器lib/fastclick.jsAndroid 設(shè)備額外監(jiān)聽mouseover、mousedown、mouseup捕獲階段click捕獲階段touchstart、touchmove、touchend、touchcancel冒泡階段。整個(gè)流程的核心是onTouchStart→onTouchMove→onTouchEnd的狀態(tài)機(jī)onTouchStartlib/fastclick.js記錄觸摸起點(diǎn)坐標(biāo)touchStartX/touchStartY、目標(biāo)元素、時(shí)間戳并處理 iOS 上文本選擇、重復(fù) touch identifier、滾動(dòng)層fling scroll等特殊情況。onTouchMovelib/fastclick.js若手指移動(dòng)超過touchBoundary默認(rèn) 10px或目標(biāo)元素變化則判定為滾動(dòng)而非點(diǎn)擊取消點(diǎn)擊追蹤。onTouchEndlib/fastclick.js驗(yàn)證點(diǎn)擊有效性后對(duì)不需要原生 click 的元素調(diào)用event.preventDefault()并執(zhí)行sendClick()立即派發(fā)合成 click。合成 click 的派發(fā)sendClick()lib/fastclick.js使用document.createEvent(MouseEvents)創(chuàng)建事件initMouseEvent注入觸摸點(diǎn)的屏幕坐標(biāo)與客戶區(qū)坐標(biāo)并設(shè)置clickEvent.forwardedTouchEvent true標(biāo)記最后通過targetElement.dispatchEvent(clickEvent)派發(fā)。這樣業(yè)務(wù)代碼里原有的click監(jiān)聽器無需任何改動(dòng)即可繼續(xù)工作。阻止重復(fù) click 與幽靈點(diǎn)擊合成 click 派發(fā)后瀏覽器隨后產(chǎn)生的原生 click 會(huì)被onMouselib/fastclick.js與onClicklib/fastclick.js攔截通過stopImmediatePropagation()/stopPropagation()preventDefault()阻止事件繼續(xù)傳播避免同一元素上出現(xiàn)雙份 click 回調(diào)。對(duì)于不支持Event.prototype.stopImmediatePropagation的舊瀏覽器如 Android 2代碼中提供了覆蓋addEventListener/removeEventListener的兼容 hacklib/fastclick.js以callback.hijacked包裝回調(diào)并按event.propagationStopped過濾。可配置的選項(xiàng)構(gòu)造函數(shù)暴露了三個(gè)可覆蓋的默認(rèn)配置項(xiàng)lib/fastclick.js選項(xiàng)默認(rèn)值說明touchBoundary10手指在touchstart與touchend之間允許移動(dòng)的最大像素距離超過即視為滾動(dòng)、取消點(diǎn)擊追蹤tapDelay200兩次 tap 之間的最小時(shí)間間隔毫秒用于阻止快速雙擊產(chǎn)生的幽靈點(diǎn)擊phantom clicks對(duì)應(yīng) issue #36tapTimeout700單次 tap 允許的最長(zhǎng)時(shí)間毫秒touchend距touchstart超過該值則不再派發(fā)合成 click使用時(shí)通過FastClick.attach(layer, options)傳入覆蓋值例如FastClick.attach(document.body, { touchBoundary: 8, tapDelay: 250, tapTimeout: 600 });兼容性FastClick 已作為 FT Web App 的一部分部署并在以下移動(dòng)瀏覽器上經(jīng)過驗(yàn)證iOS 3 及以上的 Mobile SafariiOS 5 及以上的 ChromeAndroidICS上的 ChromeOpera Mobile 11.5 及以上Android 2 以來的 Android BrowserPlayBook OS 1 及以上。源碼層面通過navigator.userAgent檢測(cè)做了大量設(shè)備特判包括deviceIsWindowsPhone、deviceIsAndroid、deviceIsIOS、deviceIsIOS4、deviceIsIOSWithBadTarget、deviceIsBlackBerry10等lib/fastclick.js分別處理 iOS 4 select 元素、iOS 6-7 目標(biāo)元素重定位、BlackBerry 10 等兼容性分支。什么時(shí)候不需要 FastClickFastClick 內(nèi)部通過FastClick.notNeeded(layer)lib/fastclick.js做自動(dòng)檢測(cè)命中以下任一場(chǎng)景時(shí)不綁定任何監(jiān)聽器桌面瀏覽器window.ontouchstart未定義時(shí)不附加任何監(jiān)聽器Android 上的 Chrome 32當(dāng) viewport meta 中包含widthdevice-width且頁面滾動(dòng)寬度不超過視口寬度時(shí)已無 300ms 延遲帶user-scalableno的 ChromeAndroid 全版本但需注意user-scalableno會(huì)同時(shí)禁用雙指縮放可能帶來無障礙accessibility方面的顧慮BlackBerry 10.3在同樣滿足 viewport 條件時(shí)IE10/IE11元素上設(shè)置了-ms-touch-action: manipulation或touch-action: manipulationnone同樣生效時(shí)雙指雙擊縮放被禁用不再需要 FastClickFirefox 27在不可縮放的 viewport 條件下無 tap 延遲。對(duì)應(yīng)地在 HTML 中聲明以下 viewport meta 即可讓新版瀏覽器天然消除延遲meta nameviewport contentwidthdevice-width, initial-scale1對(duì)于 IE11可以僅對(duì)鏈接、按鈕等特定元素使用 CSS 屬性touch-action: manipulation;禁用雙擊縮放IE10 則使用-ms-touch-action: manipulation。需要說明的是FastClick.notNeeded的自動(dòng)檢測(cè)依賴頁面加載后的 meta 標(biāo)簽與實(shí)際滾動(dòng)寬度因此腳本必須在頁面布局就緒后實(shí)例化。接入方式1. 傳統(tǒng) script 標(biāo)簽將 fastclick.js 加入你的 JavaScript bundle或在 HTML 頁面中引入script typeapplication/javascript src/path/to/fastclick.js/script腳本必須在頁面上任何元素實(shí)例化 FastClick 之前加載完成。推薦在body上實(shí)例化官方推薦用法if (addEventListener in document) { document.addEventListener(DOMContentLoaded, function() { FastClick.attach(document.body); }, false); }2. jQuery$(function() { FastClick.attach(document.body); });3. Browserify / CommonJS使用 Browserify 或其他 CommonJS 風(fēng)格模塊系統(tǒng)時(shí)require(fastclick)直接返回FastClick.attach函數(shù)因此最簡(jiǎn)用法是var attachFastClick require(fastclick); attachFastClick(document.body);這一點(diǎn)與源碼底部的模塊導(dǎo)出邏輯對(duì)應(yīng)CommonJS 環(huán)境下執(zhí)行module.exports FastClick.attach并額外暴露module.exports.FastClicklib/fastclick.js。4. 使用壓縮版Minified在當(dāng)前倉(cāng)庫(kù)根目錄運(yùn)行make即可通過 Closure Compiler REST API 構(gòu)建壓縮版Makefilemake壓縮產(chǎn)物輸出到build/fastclick.min.js。構(gòu)建腳本還通過output_infostatistics打印壓縮統(tǒng)計(jì)信息。倉(cāng)庫(kù)也提供了預(yù)壓縮版本的下載渠道通過 FT 的構(gòu)建服務(wù)預(yù)壓縮版把FastClick對(duì)象暴露為Origami.fastclick同樣具備 Browserify/CommonJS APIvar attachFastClick Origami.fastclick; attachFastClick(document.body);5. AMD 加載FastClick 支持 AMDAsynchronous Module Definition可與 RequireJS 等加載器配合實(shí)現(xiàn)懶加載。注意AMD 風(fēng)格 require 返回的是完整的FastClick對(duì)象而不是FastClick.attachvar FastClick require(fastclick); FastClick.attach(document.body, options);6. 包管理器安裝可通過 Component、npm 或 Bower 安裝。倉(cāng)庫(kù)內(nèi)已提供 package.json版本 1.0.6main指向lib/fastclick.js與 bower.json。Ruby 環(huán)境有第三方 gemfastclick-rails.NET 環(huán)境有 NuGet 包FastClick。高級(jí)用法用needsclick類忽略特定元素有時(shí)你需要讓 FastClick忽略某些元素。最簡(jiǎn)單的方式是給元素加上needsclick類a classneedsclickIgnored by FastClick/a源碼中needsClick()lib/fastclick.js會(huì)檢測(cè)元素是否帶有needsclick類命中則放行原生 click。此外button、select、textareadisabled 時(shí)、inputdisabled以及 iOS 6 上 type 為file的輸入框、label、iframe、video元素也會(huì)被自動(dòng)判定為需要原生 click。場(chǎng)景一必須使用瀏覽器原生非合成clickFastClick 內(nèi)部通過document.createEvent在touchend觸發(fā)時(shí)立即派發(fā)合成 click并抑制瀏覽器隨后產(chǎn)生的原生 click。但在某些情況下原生 click 是必需的——例如 examples/focus.html 演示的在 click 處理器中觸發(fā) input 聚焦場(chǎng)景iOS 5.0 之前觸摸事件處理器不允許以編程方式觸發(fā)其他元素聚焦只有needsclick元素放行原生 click 才能成功讓輸入框獲得焦點(diǎn)。示例頁面中元素 A 走合成 click 無法聚焦元素 B帶needsclick則能正常聚焦。場(chǎng)景二Twitter Bootstrap 2.2.2 下拉菜單Bootstrap 2.2.2 的下拉菜單自帶touchstart監(jiān)聽器需要讓 FastClick 忽略這些元素否則觸摸設(shè)備上點(diǎn)擊下拉按鈕時(shí)FastClick 與 Bootstrap 會(huì)各執(zhí)行一次合成 click導(dǎo)致下拉菜單剛打開就被立即關(guān)閉a classdropdown-toggle needsclick>贊分享前端移動(dòng)開發(fā)【免費(fèi)下載鏈接】fastclickPolyfill to remove click delays on browsers with touch UIs項(xiàng)目地址https://gitcode.com/gh_mirrors/fa/fastclick點(diǎn)擊查看免費(fèi)下載相關(guān)推薦Klein庫(kù)性能測(cè)試報(bào)告與GLM、RTM的運(yùn)算效率對(duì)比Klein庫(kù)性能測(cè)試報(bào)告與GLM、RTM的運(yùn)算效率對(duì)比 Klein是一個(gè)專注于幾何代數(shù)運(yùn)算的SIMD優(yōu)化庫(kù)基于P R _{3, 0, 1} 代數(shù)體系設(shè)計(jì)。本VUX 移動(dòng)端移除 300ms 點(diǎn)擊延遲FastClick 的正確接入方式與注意事項(xiàng)VUX 移動(dòng)端移除 300ms 點(diǎn)擊延遲FastClick 的正確接入方式與注意事項(xiàng) 導(dǎo)讀 在移動(dòng)端瀏覽器中雙擊縮放檢測(cè)機(jī)制會(huì)給普通點(diǎn)擊帶來約 300msUI組件前端Meteor fastclick 包消除移動(dòng)端 300ms 點(diǎn)擊延遲的機(jī)制、用法與棄用說明Meteor fastclick 包消除移動(dòng)端 300ms 點(diǎn)擊延遲的機(jī)制、用法與棄用說明 本文以 Meteor 倉(cāng)庫(kù)中 packages/deprecate后端前端開發(fā)工具移動(dòng)開發(fā)上一篇TQVaultAE泰坦之旅裝備管理的終極解決方案告別倉(cāng)庫(kù)爆滿煩惱下一篇從硬件報(bào)告到 EFI 生成OpCore-Simplify 黑蘋果圖形化配置完整指南創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考