一、click 和 tap 比較
兩者都會(huì)在點(diǎn)擊時(shí)觸發(fā),但是在手機(jī)WEB端,click會(huì)有 200~300 ms,所以請(qǐng)用tap代替click作為點(diǎn)擊事件。
singleTap和doubleTap 分別代表單次點(diǎn)擊和雙次點(diǎn)擊。
二、關(guān)于tap的點(diǎn)透處理
在使用zepto框架的tap來(lái)移動(dòng)設(shè)備瀏覽器內(nèi)的點(diǎn)擊事件,來(lái)規(guī)避click事件的延遲響應(yīng)時(shí),有可能出現(xiàn)點(diǎn)透的情況,即點(diǎn)擊會(huì)觸發(fā)非當(dāng)前層的點(diǎn)擊事件。
處理方式:
(1)github上有一個(gè)叫做fastclick的庫(kù),它也能規(guī)避移動(dòng)設(shè)備上click事件的延遲響應(yīng),https://github.com/ftlabs/fastclick將它用script標(biāo)簽引入頁(yè)面(該庫(kù)支持AMD,于是你也可以按照AMD規(guī)范,用諸如require.js的模塊加載器引入),并且在dom ready時(shí)初始化在body上,如:
$(function(){
new
FastClick(document.body);
})
然后給需要“無(wú)延遲點(diǎn)擊”的元素綁定click事件(注意不再是綁定zepto的tap事件)即可。
當(dāng)然,你也可以不在body上初始化它,而在某個(gè)dom上初始化,這樣,只有這個(gè)dom和它的子元素才能享受“無(wú)延遲”的點(diǎn)擊。
實(shí)踐開發(fā)中發(fā)現(xiàn),當(dāng)元素綁定fastclick后,click響應(yīng)速度比tap還要快一點(diǎn)點(diǎn)
(2)為元素綁定touchend事件,并在內(nèi)部加上e.preventDefault();
$demo.on('touchend',function(e){
// 改變了事件名稱,tap是在body上才被觸發(fā),而touchend是原生的事件,在dom本身上就會(huì)被捕獲觸發(fā)
$demo.hide()
e.preventDefault();
// 阻止“默認(rèn)行為”
})
三、touch事件touch是針對(duì)觸屏手機(jī)上的觸摸事件。現(xiàn)今大多數(shù)觸屏手機(jī)webkit內(nèi)核提供了touch事件的監(jiān)聽,讓開發(fā)者可以獲取用戶觸摸屏幕時(shí)的一些信息。
其中包括:touchstart,touchmove,touchend,touchcancel 這四個(gè)事件touchstart,touchmove,touchend事件可以類比于mousedown,mouseover ,mouseup的觸發(fā)。
touchstart: 觸摸開始的時(shí)候觸發(fā)
touchmove: 手指在屏幕上滑動(dòng)的時(shí)候觸發(fā)
touchend: 觸摸結(jié)束的時(shí)候觸發(fā)
touchcancel:系統(tǒng)停止跟蹤觸摸時(shí)候會(huì)觸發(fā)。當(dāng)一些更高級(jí)別的事件發(fā)生的時(shí)候(如電話接入或者彈出信息)會(huì)取消當(dāng)前的touch操作,即觸發(fā)ontouchcancel。一般會(huì)在ontouchcancel時(shí)暫停游戲、存檔等操作。
而每個(gè)觸摸事件都包括了三個(gè)觸摸列表,每個(gè)列表里包含了對(duì)應(yīng)的一系列觸摸點(diǎn)(用來(lái)實(shí)現(xiàn)多點(diǎn)觸控):
touches: 當(dāng)前位于屏幕上的所有手指的列表。
targetTouches: 位于當(dāng)前DOM元素上手指的列表。
changedTouches: 涉及當(dāng)前事件手指的列表。
每個(gè)觸摸點(diǎn)由包含了如下觸摸信息(常用):
identifier: 一個(gè)數(shù)值,唯一標(biāo)識(shí)觸摸會(huì)話(touch session
)中的當(dāng)前手指。一般為從0開始的流水號(hào)。
target: DOM元素,是動(dòng)作所針對(duì)的目標(biāo)。
pageX/pageX/clientX/clientY/screenX/screenY: 一個(gè)數(shù)值,動(dòng)作在屏幕上發(fā)生的位置(page包含滾動(dòng)距離,client不包含滾動(dòng)距離,screen則以屏幕為基準(zhǔn))。
radiusX/radiusY/rotationAngle: 畫出大約相當(dāng)于手指形狀的橢圓形,分別為橢圓形的兩個(gè)半徑和旋轉(zhuǎn)角度。(初步測(cè)試瀏覽器不支持,好在功能不常用,歡迎大家反饋。)
var obj = document.getElementByIdx_x('id');
obj.addEventListener('touchmove', function(event) {
// 如果這個(gè)元素的位置內(nèi)只有一個(gè)手指的話
if (event.targetTouches.length == 1) {
event.preventDefault();// 阻止瀏覽器默認(rèn)事件,重要
var touch = event.targetTouches[0];
// 把元素放在手指所在的位置
obj.style.left = touch.pageX-50 + 'px';
obj.style.top = touch.pageY-50 + 'px';
}
}, false);
但是單憑監(jiān)聽上面的單個(gè)事件,不足以滿足我們?nèi)ネ瓿杀O(jiān)聽在觸屏手機(jī)常見的一些手勢(shì)操作,如雙擊、長(zhǎng)按、左右滑動(dòng)、縮放等手勢(shì)操作。需要組合監(jiān)聽這些事件去封裝對(duì)這類手勢(shì)動(dòng)作。
其實(shí)市面上很多框架都針對(duì)手機(jī)瀏覽器封裝了這些手勢(shì),例如jqmobile、zepto、jqtouch,不過(guò)悲劇發(fā)生了,對(duì)于某些android系統(tǒng),touchmove和touchend事件不能被很好的觸發(fā),舉例子說(shuō)明下:
比如手指在屏幕由上向下拖動(dòng)頁(yè)面時(shí),理論上是會(huì)觸發(fā) 一個(gè) touchstart ,很多次 touchmove ,和最終的 touchend ,可是在android 4.0上,touchmove只被觸發(fā)一次,觸發(fā)時(shí)間和touchstart 差不多,而touchend直接沒有被觸發(fā)。
暫時(shí)我只發(fā)現(xiàn)在android 4.0會(huì)有這個(gè)bug,據(jù)說(shuō) iOS 3.x的版本也會(huì)有。
而顯然jqmobile、zepto等都沒有意識(shí)到這個(gè)bug對(duì)監(jiān)聽實(shí)現(xiàn)帶來(lái)的嚴(yán)重影響,所以在直接使用這些框架的event時(shí),或多或少會(huì)出現(xiàn)兼容性問題!
四、gesture事件
Gesture事件,包括手指點(diǎn)擊(click),輕拂 (flick),雙擊(double-click),手指的分開、閉合(scale)、轉(zhuǎn)動(dòng)(rotate)等一切手指能在屏幕上做的事情,它只在有兩根 或多根手指放在屏幕上的時(shí)候觸發(fā),事件處理函數(shù)中會(huì)得到一個(gè)GestureEvent類型的參數(shù),它包含了手指的scale(兩根移動(dòng)過(guò)程中分開的比例) 信息和rotation(兩根手指間連線轉(zhuǎn)動(dòng)的角度)信息。這個(gè)事件是對(duì)touch事件的更高層的封裝,和touch一樣,它同樣包括 gesturestart,gesturechange,gestureend。gesture事件觸發(fā)過(guò)程:Step 1、第一根手指放下,觸發(fā)touchstartStep 2、第二根手指放下,觸發(fā)gesturestartStep 3、觸發(fā)第二根手指的touchstartStep 4、立即觸發(fā)gesturechangeStep 5、手指移動(dòng),持續(xù)觸發(fā)gesturechange,就像鼠標(biāo)在屏幕上移動(dòng)的時(shí)候不停觸發(fā)mousemove一樣Step 6、第二根手指提起,觸發(fā)gestureend,以后將不會(huì)再觸發(fā)gesturechangeStep 7、觸發(fā)第二根手指的touchendStep 8、觸發(fā)touchstart!注意,多根手指在屏幕上,提起一根,會(huì)刷新一次全局touch!重新觸發(fā)第一根手指的touchstartStep 9、提起第一根手指,觸發(fā)touchend