1. 程式人生 > >移動端web,tap與click事件

移動端web,tap與click事件

document 解決 取消 list 所有 ons scrip 還要 時間

一、tap與click的區別

兩者都會在點擊時系統自動觸發,但是在手機WEB端,click會有 200~300 ms。延遲來自判斷雙擊和長按,因為只有默認等待時間結束以確定沒有後續動作發生時,才會觸發click事件。所以觸摸事件反應更快,體驗更好。
singleTap和doubleTap 分別代表單次點擊和雙次點擊。
tap封裝了touchstart、touchmove、touchend三個事件的處理(touchstart之後如果有產生touchmove則取消此次tap事件的產生) click則只是單純的綁定了瀏覽器的click事件。

二、tap事件點透問題

點擊會觸發非當前層的點擊事件,這就是點透。例如:點擊a但是同時觸發了b元素的click事件,因為tap事件是通過document綁定了touchstart和touchend事件實現,$(‘.a‘)上,當touchend事件冒泡到document上以後執行$(this).hide();此時$(‘.b‘),就處在了頁面的最前面,現在touchend冒泡到了document上,並且$(‘.b‘)在頁面的最前面,然後就觸發了click事件。

三、tap事件點透解決

1.github上有一個叫做fastclick的庫,它能規避移動設備上click事件的延遲響應https://github.com/ftlabs/fastclick將它用script標簽引入頁面(該庫支持AMD,可按照AMD規範,用require.js的模塊加載器引入),並且在dom ready時初始化在body上,如:
$(function(){
new FastClick(document.body);
})

然後給需要“無延遲點擊”的元素綁定click事件(註意不再是綁定zepto的tap事件)即可。
也可以不在body上初始化它,而在某個dom上初始化,這樣,只有設個dom和它的子元素才能享受"無延遲"的點擊。

因為fastclick源碼不依賴其他庫所以你可以在原生的js前直接加上
window.addEventListener( "load", function() {
FastClick.attach( document.body );
}, false );

或者有zepto或者jqm的js裏面加上
$(function() {
FastClick.attach(document.body);
});

當然require的話就這樣:
var FastClick = require("fastclick");
FastClick.attach(document.body, options);

實踐開發中,當元素綁定fastclick後,click響應速度比tap還要快一點。
2.對於B元素本身存在默認click事件的情況,應用touchend代替tap事件並阻止掉A元素touchend的默認行為preventDefault(),從而阻止click事件的產生。
$("#aa").on("touchend", function (event) {
//很多處理比如隱藏什麽的
event.preventDefault();
});

對於B元素本身沒有默認click事件的情況(無a標簽等),應統一使用touch事件,統一代碼風格,並且由於click事件在移動端的延遲要大很多,不利於用戶體驗,所以關於觸摸事件應盡量使用touch相關事件。

延遲一定的時間(300ms+)來處理事件
$("#aa").on("tap", function (event) {
setTimeout(function(){
//很多處理比如隱藏什麽的
},320);
});

這種方法其實很好,可以和fadeInIn/fadeOut等動畫結合使用,可以做出過度效果

理論上上面的方法可以完美的解決tap的點透問題,如果真的倔強到不行,改用click。特別是對於遮蓋浮層,由於遮蓋浮層的點擊即使有小延遲也是沒有關系的,反而會有疑似更好的用戶體驗,所以這種情況,可以針對遮蓋浮層自己采用click事件,這樣就不會出現點透問題。



如何解決穿透:

方法一:直接將上層元素的tap事件換成click事件(會出現300ms的延遲觸發事件)

方法二:在click事件觸發前阻止它,如在touchend的事件中使用e.preventDefault()來阻止後續的click事件

zepto為何不使用e.preventDefault()來解決穿透問題?

因為zepto的tap事件統一是在document的touchend時觸發的,若在這裏使用e.preventDefault(),那頁面上所有元素在touchend後觸發的事件都不會被執行了。



移動端web,tap與click事件