fastclick.js移動端WEB開發,click,touch,tap事件淺析
一、click 和 tap 比較
兩者都會在點選時觸發,但是在手機WEB端,click會有 200~300 ms,所以請用tap代替click作為點選事件。
singleTap和doubleTap 分別代表單次點選和雙次點選。
二、關於tap的點透處理
在使用zepto框架的tap來移動裝置瀏覽器內的點選事件,來規避click事件的延遲響應時,有可能出現點透的情況,即點選會觸發非當前層的點選事件。
處理方式:
(1)、
github上有一個叫做fastclick的庫,它也能規避移動裝置上click事件的延遲響應,https://github.com/ftlabs/fastclick 將它用script標籤引入頁面(該庫支援AMD,於是你也可以按照AMD規範,用諸如require.js的模組載入器引入),並且在dom ready時初始化在body上,如:
1
2
3
$(function(){
newFastClick(document.body);
- 1
}) 然後給需要“無延遲點選”的元素繫結click事件(注意不再是繫結zepto的tap事件)即可。 當然,你也可以不在body上初始化它,而在某個dom上初始化,這樣,只有這個dom和它的子元素才能享受“無延遲”的點選
實踐開發中發現,當元素繫結fastclick後,click響應速度比tap還要快一點點。哈哈
(2)、為元素繫結touchend事件,並在內部加上e.preventDefault();
$demo.on(‘touchend’,function(e){//
改變了事件名稱,tap是在body上才被觸發,而touchend是原生的事件,在dom本身上就會被捕獲觸發
$demo.hide()e.preventDefault();//
- 1
- 2
- 3
阻止“預設行為”
})
三、touch事件touch是針對觸屏手機上的觸控事件。現今大多數觸屏手機webkit核心提供了touch事件的監聽,讓開發者可以獲取使用者觸控式螢幕幕時的一些資訊。
其中包括:touchstart,touchmove,touchend,touchcancel 這四個事件
touchstart,touchmove,touchend事件可以類比於mousedown,mouseover
,mouseup的觸發。
touchstart : 當手指觸控到螢幕會觸發;
touchmove : 當手指在螢幕上移動時,會觸發;
touchend : 當手指離開螢幕時,會觸發;
而touchcancel許多人不知道它在什麼時候會被觸發而忽略它,其實當你的手指還沒有離開螢幕時,有系統級的操作發生時就會觸發touchcancel,例如alert和confirm彈框,又或者是android系統的功能彈窗。
例如:
這4個事件的觸發順序為:
touchstart -> touchmove -> …… -> touchmove ->touchend
但是單憑監聽上面的單個事件,不足以滿足我們去完成監聽在觸屏手機常見的一些手勢操作,如雙擊、長按、左右滑動、縮放等手勢操作。需要組合監聽這些事件去封裝對這類手勢動作。
其實市面上很多框架都針對手機瀏覽器封裝了這些手勢,例如jqmobile、zepto、jqtouch,不過悲劇發生了,對於某些android系統(我自己測試到的在android 4.0.x),touchmove和touchend事件不能被很好的觸發,舉例子說明下:
比如手指在螢幕由上向下拖動頁面時,理論上是會觸發 一個 touchstart ,很多次 touchmove ,和最終的 touchend ,可是在android 4.0上,touchmove只被觸發一次,觸發時間和touchstart 差不多,而touchend直接沒有被觸發。這是一個非常嚴重的bug,在google Issue已有不少人提出 http://code.google.com/p/android/issues/detail?id=19827
暫時我只發現在android 4.0會有這個bug,據說 ios 3.x的版本也會有。
而顯然jqmobile、zepto等都沒有意識到這個bug對監聽實現帶來的嚴重影響,所以在直接使用這些框架的event時,或多或少會出現相容性問題!
為什麼存在延遲?
根據 Google 開發者文件:
…mobile browsers will wait approximately 300ms from the time that you tap the button to fire the click event. The reason for this is that the browser is waiting to see if you are actually performing a double tap. 從點選螢幕上的元素到觸發元素的 click 事件,移動瀏覽器會有大約 300 毫秒的等待時間。為什麼這麼設計呢? 因為它想看看你是不是要進行雙擊(double tap)操作。
相容性
Mobile Safari on iOS 3 and upwards Chrome on iOS 5 and upwards Chrome on Android (ICS) Opera Mobile 11.5 and upwards Android Browser since Android 2 PlayBook OS 1 and upwards 不應用 FastClick 的場景
桌面瀏覽器; 如果 viewport meta 標籤 中設定了 width=device-width, Android 上的 Chrome 32+ 會禁用 300ms 延時; Copy viewport meta 標籤如果設定了 user-scalable=no,Android 上的 Chrome(所有版本)都會禁用 300ms 延遲。 IE10 中,可以使用 css 屬性 -ms-touch-action: none 禁止元素雙擊縮放(參考文章)。 使用方法
TODO: 修改使用介面
Copy window.addEventListener(‘load’, function() { FastClick.attach(document.body); }, false); Zepto.js:
Copy $(function() { FastClick.attach(document.body); }); Copy var attachFastClick = require(‘fastclick’); attachFastClick(document.body); Licence
@copyright The Financial Times Limited [All Rights Reserved] @license MIT License