事件穿透

2018-10-16  本文已影响0人  李昂李三光

事件穿透是很多中级软件工程师面试时会问起的一个重点

在触发某些事件时,有时会将div下面的事件也一并触发,这种时候,就是所谓的事件穿透。事件穿透是有发生条件的

  1. 在移动端的情况下
  2. 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>

解决方法

  1. 不将click事件和touchstart事件混合使用
  2. 使用fastclick.js插件解决
上一篇下一篇

猜你喜欢

热点阅读