什么是click點(diǎn)透诗力?
核心代碼:
<div class="content">
<div id="underLayer">
<a href="www.baidu.com">鏈接</a>
<input type="text" class="text1" >
<input type="select" class="select">
<input type="radio" class="select">
<input type="checkbox" class="select">
<button class="btn" id="openPopup">彈出</button>
</div>
<div id="popupLayer">
<div class="layer-title">彈出層</div>
<div class="layer-action">
<button class="btn" id="closePopup">關(guān)閉</button>
</div>
</div>
</div>
<script type="text/javascript">
var oPop =document.getElementById('popupLayer');
var oUn = document.getElementById('underLayer');
var oOpen = document.getElementById('openPopup');
oPop.addEventListener('touchend', function(e){
this.style.display='none';
});
oUn.addEventListener('click',
function(){
alert('1');
} );
</script>
點(diǎn)擊彈出層捷兰,touch事件首先被觸發(fā)出革,彈出層和遮罩就被隱藏了贝或。touchend后繼續(xù)等待300ms發(fā)現(xiàn)沒有其他行為了,則繼續(xù)觸發(fā)click泼诱,由于這時(shí)彈出層已經(jīng)消失坛掠,所以當(dāng)前click事件的target就在底層元素上,于是就alert內(nèi)容治筒。整個(gè)事件觸發(fā)過程為 touchend -> click屉栓。
而由于click事件的滯后性(300ms),在這300ms內(nèi)上層元素隱藏或消失了耸袜,下層同樣位置的DOM元素觸發(fā)了click事件(如果是input框則會(huì)觸發(fā)focus事件友多,如果是<a>鏈接則會(huì)進(jìn)行頁(yè)面跳轉(zhuǎn),或是 select / radio / checkbox都會(huì)被觸發(fā))堤框,看起來就像點(diǎn)擊的target“穿透”到下層去了域滥。這就是點(diǎn)透現(xiàn)象
解決方法:
a、阻止默認(rèn)事件 e.preventDefault() 給touchend事
件加上 e.preventDefault()
oPop.addEventListener('touchend', function(e){
this.style.display='none';
e.preventDefault();
});
b蜈抓、利用css3屬性 pointer-events
取值auto|none
當(dāng)取值為auto 時(shí)启绰,效果和沒有定義 pointer-events 屬性相同,鼠標(biāo)不會(huì)穿透當(dāng)前層沟使。
當(dāng)取值為none 時(shí)委可,元素不再是鼠標(biāo)事件的目標(biāo),鼠標(biāo)不再監(jiān)聽當(dāng)前層而去監(jiān)聽下面的層中的元素腊嗡。但是如果它的子元素設(shè)置了pointer-events為其它值着倾,比如auto拾酝,鼠標(biāo)還是會(huì)監(jiān)聽這個(gè)子元素的。
詳細(xì)代碼:
oPop.addEventListener('touchend', function(e){
this.style.display='none';
oUn.style.pointerEvents='none';
setTimeout(function(){
oUn.style.pointerEvents='auto';
}, 400);
});
c. 遮擋
由于 click 事件的滯后性卡者,在這段時(shí)間內(nèi)原來點(diǎn)擊的元素消失了蒿囤,于是便“穿透”了。因此我們順著這個(gè)思路就想到崇决,可以給元素的消失做一個(gè)fade效果蟋软,類似jQuery里的fadeOut,并設(shè)置動(dòng)畫duration大于300ms嗽桩,這樣當(dāng)延遲的 click 觸發(fā)時(shí),就不會(huì)“穿透”到下方的元素了凄敢。
同樣的道理碌冶,不用延時(shí)動(dòng)畫,我們還可以在觸摸位置放一個(gè)透明的元素涝缝,這樣當(dāng)上層元素消失而延遲的click來到時(shí)扑庞,它點(diǎn)擊到的是那個(gè)透明的元素,也不會(huì)“穿透”到底下拒逮。在一定的timeout后再將生成的透明元素隱藏罐氨。代碼如下:
oPop.addEventListener('touchend', function(e){
oBg.style.display ='block';
this.style.display='none';
// 解決方法三
setTimeout(function(){
oBg.style.display='none'
}, 400);
});
參考徹底理解和解決移動(dòng)WEB開發(fā)中CLICK點(diǎn)透問題