美文网首页
click事件执行两次??

click事件执行两次??

作者: Apollozz | 来源:发表于2018-05-16 19:26 被阅读0次

    问题描述

    在项目中遇到一个bug——label标签上绑定了一个返回一层的点击事件,然鹅每次点击都会返回两层!!

    经调试发现,label标签中包裹input,而事件绑定在label标签中时,点击label区域,事件会执行两次。

    问题测试

    <label onclick="labelConsole()">
      <input type="checkbox" onclick="inputConsole()">勾选协议
    </label>
    
    function labelConsole (){
      console.log('label_click 这是我们想要的操作')
    }
    function inputConsole (){
      console.log('input_click')
    }
    
    1. 点击label区域(不直接点击input区域):label上的事件被触发执行一次,同时子元素input本身也绑定有click事件,触发后又冒泡传递给label,又触发了一次label绑定事件。


    2. 直接点击input区域:触发input绑定事件后又冒泡传递给label,触发了label的绑定事件。


    分析原因

    1. 元素默认绑定click事件
      一些元素如<a>、<button>、<input>本生就默认绑定了click事件,即使你不绑定,click事件发生时他们也会接收到。
    2. label标签的扩展性
      它把所包含的input的用户交互区域扩展了,注意的是label和所包含的input都开始绑定默认事件,此时会发生事件冒泡现象。在label上的click事件的处理函数会触发2次就是由于:第一次是label自己接收到事件,执行处理函数,第二次是input接受到事件后冒泡传递给label,再次触发处理函数。

    解决方案

    方案1:将原绑定于label的事件,直接绑定于input上。

    <label>
      <input type="checkbox" onclick="labelConsole()">勾选协议
    </label>
    

    此时,当点击label区域或者直接点击input区域,由于checkbox本身有默认click监听器,所以会触发一次我们绑定的事件。

    方案2:阻止事件冒泡

    <label onclick="labelConsole()">
      <input type="checkbox" onclick="inputConsole()">勾选协议
    </label>
    
    function labelConsole (){
      console.log('label_click 这是我们想要的操作')
    }
    function inputConsole (){
      console.log('input_click');
      window.event? window.event.cancelBubble = true : e.stopPropagation();
    }
    

    点击label非input区域的时候效果如上,这种方法看似实现了我们的需求,只让我们想要的操作触发一次,但是如果你直接点击的是input,那就跪了。没错,当你直接点击input的时候只会触发input的绑定事件,而我们绑定在label上的事件则无人问津。这并不符合预期,所以方案2不太可取。

    相关文章

      网友评论

          本文标题:click事件执行两次??

          本文链接:https://www.haomeiwen.com/subject/ygppdftx.html