为什么 onclick 元素会为 label 元素触发两次

新手上路,请多包涵
       window.onload = function(){
         var wow = document.getElementById("wow");
    	 wow.onclick = function(){
    	     alert("hi");
    	 }
      }
     <label id="wow"><input type="checkbox" name="checkbox" value="value">Text</label>

这是我的代码,当我点击“文本”时,它会提示 hi 两次,但是当我点击该框时, onclick 元素只会触发一次,为什么?

原文由 dramasea 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 322
2 个回答

当您点击标签时,它会触发点击处理程序,您会收到警报。

但是单击标签也会自动向关联的输入元素发送单击事件,因此这被视为单击复选框。然后事件冒泡导致在包含元素(即标签)上触发单击事件,因此您的处理程序再次运行。

如果您将 HTML 更改为此,您将不会收到双重警报:

 <input id="wowcb" type="checkbox" name="checkbox" value="value">
<label id="wow" for="wowcb">Text</label>

标签现在使用 for 属性与复选框相关联,而不是环绕它。

演示

原文由 Barmar 发布,翻译遵循 CC BY-SA 3.0 许可协议

如果您打算只响应标签上的点击而不是复选框上的点击,您可以查看 event.target 属性。它引用调用侦听器的元素,因此如果点击不在该元素上,则不要执行操作:

 window.onload = function(){
  var el = document.getElementById('wow');
  el.addEventListener('click', function(event) {

    if (this === event.target) {
      /* click was on label */
      alert('click was on label');

    } else {
      /* click was on checkbox */
      event.stopPropagation();
      return false;
    }

  }, false);
}

另一方面,如果您只想响应对复选框的点击(点击标签也会产生对复选框的点击),则执行相反的操作。对标签上的点击不执行任何操作,让复选框中的点击通过:

 window.onload = function(){
  var el = document.getElementById('foolabel');
  el.addEventListener('click', function(event) {

    if (this === event.target) {
      /* click was on label */
      event.stopPropagation();
      return false;

    } else {

      /*
      ** click is from checkbox, initiated by click on label
      ** or checkbox
      */

      alert('click from checkbox');
    }

  }, false);
}

这个版本似乎有最自然的行为。但是,更改标记以使标签不再包裹复选框将意味着不会调用侦听器。

原文由 RobG 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题