解析JS绑定事件重复触发问题

来源:互联网 发布:淘宝商城一元秒杀 编辑:程序博客网 时间:2024/06/07 01:09

一、什么问题

当前端开发过程中,经常用到事件,随着业务代码这一块的复杂化,在事件和多次注册和调用时,如果处理不好就会出现同一事件触发多次的问题。今天我们就聊一聊这个问题


二、事例

下面这段代码是一个简单的例子,页面上一有一个安钮。当点击’安钮‘时创建一个button为 test button代码插入area中。接着点击该button,console.log一个东西。如果下代码:

html结构:

<body>
<div id="tableBox" class="add">安钮</div>
<div class="area"></div>
</body>

css:

#tableBox{
width:100px;
height:30px;
background:red;
border:1px solid red;
text-align:center;
line-height:30px;
border-radius:5px;
}
.area{
width:100px;
height:100px;
margin-top:40px;
border:2px;
border:1px solid #000;
}

js代码:

$(function(){
    $(".add").on('click',function(eve){
      $(".area").append("<button class='test-btn'>test button</button>");      
      $(".area").on('click','.test-btn',function(event){
        console.log("test button .....");   
       
      });
    });
});

运行此段代码结果是:当第一次点击’安钮‘时,成功创建了一个button,再点击这个button执行打印出test button...,此时看一切都是那么正常,可是接着再点击第二次’安钮‘时,此时创建出来第二个button时,再点击刚才第一次创建出来的button,打印出来了3次,也就是说点击一次。执行了二次代码。以此类推。第三次时,就执行了三次代码。。。


三、原因


此时我们分析上面这段代码这么写有什么问题。为什么会事件会累加执行?可以看出出第二次的事件绑定和第一次的事件绑定都注册到了同一个DIV身上,在JQ中事件注册同时注册到同一个DIV身时。只要不消毁就会累计执行。这就是根本 原因所在。可能有的人此时想到是不是因为事件冒泡的原因,那我们阻止完了事件冒泡结果是什么呢?

$(function(){
    $(".add").on('click',function(eve){
      $(".area").append("<button class='test-btn'>test button</button>");      
      $(".area").on('click','.test-btn',function(event){

        event.stopPropagation();
        console.log("test button .....");     
       
      });
    });
});

事实结果是一样的。这个跟事件冒泡没有根本上的联系,如果那我是不是只有在绑定时才会出现累计打执行呢。那我们来试下不用on的执行结果是什么


$(function(){
    $(".add").click(function(eve){
      $(".area").append("<button class='test-btn'>test button</button>");      
      $(".test-btn").click(function(){
        console.log("test button .....");
      });
    });
});


结果依然一样,在事件执行的时候在同一个元素上注册执行的事件还是执行了多次。那如何解决这个问题


四、解决方法:


1)绑定之前先解绑

$(function(){
    $(".add").on('click',function(eve){
      $(".area").append("<button class='test-btn'>test button</button>");

     //解除
      $(".area").off("click");

     //再绑定
      $(".area").on('click','.test-btn',function(event){

        console.log("test button .....");
        event.stopPropagation();
       
      });
    });
});


2)分开写


$(function(){
    $(".add").on('click',function(eve){
      $(".area").append("<button class='test-btn'>test button</button>");
      
    });

     $(".area").on('click','.test-btn',function(){
        console.log("test button .....");
            
      });
});


总结:上面列举的只不过是一个小例子,在工作当开发会碰到比这更复杂更多的多层事件问题,尤其在多个URL请求时,如果处理不好,大家不自测和检查自己的代码,就会出来事件一次。多次请求的问题。这些问题也是在公司团队中的同事经常犯的一些错误,所以在今后开发的过程中,要养成一个好的编程习惯 ,才能保证代码的更强壮。




原创粉丝点击