Web前端 移动端click点透事件

最近在做微信wap 站时遇到 这样一个现象,给页面加一个遮罩层,点击遮罩层,遮罩层消失,如果页面内input 框,input 框会自动获取焦点,上网搜了一下,原来是“click点透事件”,
什么是click点透
核心代码:
<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”>关闭</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>
点击弹出层,touch事件首先被触发,弹出层和遮罩就被隐藏了。touchend后继续等待300ms发现没有其他行为了,则继续触发click,由于这时弹出层已经消失,所以当前click事件的target就在底层元素上,于是就alert内容。整个事件触发过程为 touchend -> click。
而由于click事件的滞后性(300ms),在这300ms内上层元素隐藏或消失了,下层同样位置的DOM元素触发了click事件(如果是input框则会触发focus事件,如果是<a>链接则会进行页面跳转,或是 select / radio / checkbox都会被触发),看起来就像点击的target“穿透”到下层去了。这就是点透现象
2.解决方法:
a、阻止默认事件 e.preventDefault() 给touchend事件加上 e.preventDefault()
oPop.addEventListener(‘touchend’, function(e){
this.style.display=’none’;
e.preventDefault();
});
b、利用css3属性 pointer-events
取值auto|none
当取值为auto 时,效果和没有定义 pointer-events 属性相同,鼠标不会穿透当前层。
当取值为none 时,元素不再是鼠标事件的目标,鼠标不再监听当前层而去监听下面的层中的元素。但是如果它的子元素设置了pointer-events为其它值,比如auto,鼠标还是会监听这个子元素的。
详细代码:
oPop.addEventListener(‘touchend’, function(e){
this.style.display=’none’;
oUn.style.pointerEvents=’none’;
setTimeout(function(){
oUn.style.pointerEvents=’auto’;
}, 400);
});
c. 遮挡
由于 click 事件的滞后性,在这段时间内原来点击的元素消失了,于是便“穿透”了。因此我们顺着这个思路就想到,可以给元素的消失做一个fade效果,类似jquery里的fadeOut,并设置动画duration大于300ms,这样当延迟的 click 触发时,就不会“穿透”到下方的元素了。
同样的道理,不用延时动画,我们还可以在触摸位置放一个透明的元素,这样当上层元素消失而延迟的click来到时,它点击到的是那个透明的元素,也不会“穿透”到底下。在一定的timeout后再将生成的透明元素隐藏。代码如下:
oPop.addEventListener(‘touchend’, function(e){
oBg.style.display =’block’;
this.style.display=’none’;
// 解决方法三
setTimeout(function(){
oBg.style.display=’none’
}, 400);
});
开发前端框架的原则|前端移动端开发规范|vue 前端框架 开发者
» 本文来自:前端开发者 » 《Web前端 移动端click点透事件》
» 本文链接地址:https://www.rokub.com/5200.html
» 您也可以订阅本站:https://www.rokub.com
赞(0)
64K

评论 抢沙发

评论前必须登录!