click点透

什么是click点透?

核心代码:



链接







弹出层





点击弹出层,touch事件首先被触发,弹出层和遮罩就被隐藏了。touchend后继续等待300ms发现没有其他行为了,则继续触发click,由于这时弹出层已经消失,所以当前click事件的target就在底层元素上,于是就alert内容。整个事件触发过程为 touchend -> click。
而由于click事件的滞后性(300ms),在这300ms内上层元素隐藏或消失了,下层同样位置的DOM元素触发了click事件(如果是input框则会触发focus事件,如果是链接则会进行页面跳转,或是 select / radio / checkbox都会被触发),看起来就像点击的target“穿透”到下层去了。这就是点透现象

解决方法:
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);

     
  });

参考彻底理解和解决移动WEB开发中CLICK点透问题

你可能感兴趣的:(click点透)