点击穿透

1 什么是点击穿透

遮罩层元素的下一面有一个链接元素。
遮罩层绑定 touchstart 事件,  被触发后希望遮罩层消失,真实的状况是这时候点击遮罩层不见的同时会跳转页面。

2 点击穿透的原因

超链接元素具有 click 特性。

touchstart 会先于 click 事件执行,当上述的这个遮罩层消失后, 300ms之后他底下的具有点击特性的元素会被触发。

3 解决点击穿透

3.1 阻止上层元素的默认动作 (推荐)

 event.preventDefault();

3.2 阻止所有元素的默认动作 (推荐)

/*阻止所有元素的默认点击动作*/
document.addEventListener("touchstart",function(ev){
 ev.preventDefault();
});

/* 为提高性能,chrome56之后, window docuemnt body 触屏事件默认无法取消默认事件, 需要给 addEventListener() 指定第三个参数 */
document.addEventListener("touchstart",function(ev){
 ev.preventDefault();
}, {passive: false});


/* 或者给最外城的包裹元素 绑定touchstart事件 并阻止默认行为;/ */
document.addEventListener("touchstart",function(ev){
 ev.preventDefault();
});
/*给 链接元素 添加 touchstart 事件*/
var aList = document.querySelectorAll('a[href]');
for (var i = 0; i < aList.length; i ++) {
    aList[i].addEventListener('touchstart', function() {
      location.href = this.href;
  })
}

3.3 下层元素不使用点击特性的元素

使用没有点击特性的元素来代替 a 元素

3.4 利用CSS属性 pointer-events

pointer-events 属性指定在什么情况下 某个特定的元素可以成为鼠标事件的目标

常用值:

取值 含义
auto 默认值
none 元素不再是鼠标事件的目标

原理:

  • 当触发上层元素的 touchstart 事件时,设置底层链接元素的 CSS 属性pointer-events 值为 none
  • 设置单次定时,一定要超过 300ms, 再把底层链接元的 CSS 属性 pointer-events 值变为为 auto
opacity.addEventListener('touchstart', closeModal);

function closeModal() {
  opacity.style.display = 'none';
  link.style.pointerEvents = 'none';
  setTimeout(function(){
    link.style.pointerEvents = 'auto';
  }, 400);
}

3.5 上层元素不要立即消失

不要要元素立马就消失,300s 之后再消失。

opacity.addEventListener('touchstart', closeModal);
function closeModal() {
  setTimeout(function(){
    opacity.style.display = 'none';
  }, 400);
}

results matching ""

    No results matching ""