面试题:点透事件

一、先上一段代码大家直观地看看现象(可以复制,在浏览器中打开)


<!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事件没有延迟.

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值