一、先上一段代码大家直观地看看现象(可以复制,在浏览器中打开)
<!DOCTYPE html>
<html>
<head>
<style type="text/css">
#box {
position: relative;
}
#box1 {
position: absolute;
z-index: 1;
background: red;
width: 200px;
height: 200px;
}
#box2{
background: green;
width: 200px;
height: 200px;
}
</style>
</head>
<body>
<div id="boxparent">
<div id="box1">
</div>
<div id="box2">
</div>
</div>
</body>
<script type="text/javascript">
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
box1.ontouchstart=function(e) {
console.log('box1被摸了');
box1.style.display = 'none';
};
box2.onclick = function() {
console.log('box2被点了');
}
</script>
</html>
打开浏览器,在浏览器窗口看到了(注意是移动端的,使用google模拟器):
当你在红色区域点击鼠标时,在控制台看到了:
即:触发了box1的ontouchstart后,又触发了box2的onclick事件。
怎么回事?
box1和box2不是父子关系,为什么会有这种情况出现?这就是所谓的“点透”
二、点透是什么
1、box1 和 box2两个元素不是后代和继承关系(如果是后代继承关系的话,就直接是冒泡了), box1的z-index大于box2,即box1显示在box2浮层之上
2、box1元素发生touch, box1在touch事件后立即消失,
3、box2事件绑定click。
以上代码的执行过程:
当用户手指接触到box1时,
1、会触发touchstart和click两个事件,先触发touchstart事件
2、在touchstart里隐藏box1
3、click事件的触发有200-300ms的延时
4、等到click事件要触发时,发现只有box2了(box1被隐藏了),
5、所以,就只能触发box2的click事件。
强调:点透是元素之间没有父子关系,只是由于click在移动端里有200-300ms的延时造成的。
四、如何解决点透(使用preventDefault)
把以上代码中的javascript改为:
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
box1.ontouchstart=function(event) {
console.log('box1被摸了');
box1.style.display = 'none';
};
box1.ontouchend=function(event) {
console.log('box1被摸完了');
event.preventDefault(); //也可以根据实际情况,写在touchstart里
};
box2.onclick = function() {
console.log('box2被点了');
}
解释:用户一个触摸屏幕的动作,会引发两个事件,分别是touchstart和click。但是touchstart的优先级高。所以,可以在touchstart中用preventDefault()在阻止浏览器的默认行为,进而不再触发click事件,或者在touchend中使用preventDefault也可以。
五、点透和冒泡:
冒泡:是元素之间存在父子关系
点透:元素之间没有父子关系,只是由于click在移动端里有200-300ms的延时造成的。
为了更好理解,可以看看如下代码(把以上代码的js改为如下):
var box1 = document.getElementById("box1");
var box2 = document.getElementById("box2");
box1.ontouchstart=function(e) {
console.log('box1被摸了');
box1.style.display = 'none';
};
box2.ontouchstart=function(e) {
console.log('box2被摸了');//不会被触发,因为,不是父子关系,没有冒泡
};
box2.onclick = function() {
console.log('box2被点了');
}
六、pc端有点透事件吗?
pc端没有点透事件.因为,在pc端时,用户用鼠标点击时,click事件没有延迟.