點透現象出現的場景:前端
當A/B兩個層上下z軸重疊,上層的A點擊後消失或移開(這一點很重要),而且B元素自己有默認click事件(如a標籤)或綁定了click事件。在這種狀況下,點擊A/B重疊的部分,就會出現點透的現象。git
點透現象出現的緣由:github
zepto的tap事件是經過兼聽綁定在document上的touch事件來完成tap事件的模擬的,而且tap事件是冒泡到document上觸發的!!!瀏覽器
在移動端不使用click而用touch事件代替觸摸是由於click事件有着明顯的延遲,具體touchstart與click的區別以下:動畫
touchstart:在這個DOM(或冒泡到這個DOM)上手指觸摸開始即能當即觸發;ui
click:在這個DOM(或冒泡到這個DOM)上手指觸摸開始,且手指不曾在屏幕上移動(某些<a href=」http://www.jd.com」>瀏覽器</a>容許移動一個很是小的位移值),且在這個DOM上手指離開屏幕,且觸摸和離開屏幕之間的間隔時間較短(某些瀏覽器不檢測間隔時間,也會觸發click)才能觸發事件
也就是說,在移動端事件的觸發時間按由早到晚排列爲:touchstart 早於 touchend 早於 click。亦即click的觸發是有延遲的,這個時間大概在300ms左右。zepto
因爲咱們在touchstart階段就已經隱藏了罩層A,當click被觸發時候,可以被點擊的元素則是其下的B元素,根據click事件的觸發規則:只有在被觸發時,當前有click事件的元素顯示,且在面朝用戶的最前端時,才觸發click事件。因爲B綁定了click事件(或者B自己默認存在click事件),因此B的click事件被觸發,產生了點透的狀況。源碼
點透現象解決方案:it
解決方案一:來得很直接github上有個fastclick能夠完美解決https://github.com/ftlabs/fastclick
引入fastclick.js,由於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);
解決方案二:
對於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事件,這樣就不會出現點透問題。