事件穿透是很多中级软件工程师面试时会问起的一个重点
在触发某些事件时,有时会将div下面的事件也一并触发,这种时候,就是所谓的事件穿透。事件穿透是有发生条件的
- 在移动端的情况下
-
click
事件和touchstart
这种触发时长不相同的事件混合使用时
原理:事件的响应时间不同,有一部分事件(比如click)触发后会有300ms的延迟,这是因为延迟时间用于判断用户是单击还是双击,如果前面的事件触发时间短,触发之后,div隐藏了,导致300ms之后,e.target为遮罩层后面的元素,如果恰好后面的元素有注册click事件,就会被触发
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title></title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<style type="text/css">
*{
padding: 0;
margin: 0;
}
button{
background-color: skyblue;
margin-right: 10px;
}
.content{
width: 100%;
height: 320px;
background-color: red;
}
.mask{
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0,0,0,0.7);
}
</style>
</head>
<body>
<!--事件穿透的原理
事件穿透是很多中级工程师的面试题
事件的响应速度
touchstart>click
click事件在移动端有300ms的延迟,用来判断用户是单击还是双击-->
<!--由于当前遮罩层的元素触发touch事件之后,隐藏了,导致300ms之后,e.target为遮罩层后面的元素,如果恰好
后面的元素有注册click事件,就会被触发-->
<div class="baba">
<button class="show">
显示
</button>
<button class="hidden">隐藏</button>
<div class="content">我是文本</div>
</div>
<div class="mask">
<button class="close">关闭遮罩层</button>
</div>
<script type="text/javascript">
var close=document.querySelector(".close");
var mask=document.querySelector(".mask")
var show = document.querySelector(".show");
var hidden = document.querySelector(".hidden");
var content = document.querySelector(".content");
show.onclick=function(){
content.style.display="block";
}
hidden.onclick=function(){
content.style.display="none";
}
// close.ontouchstart=function(){
// mask.style.display="none";
// }
close.addEventListener("touchstart",function(){
mask.style.display="none";
})
// 解决办法是不混用click和touchstart方法
// 或者是使用fastclick.js解决
</script>
</body>
</html>
解决方法
- 不将click事件和touchstart事件混合使用
- 使用fastclick.js插件解决
网友评论