点击穿透
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);
}