今天帮群里的朋友看一段代码的时候偶然间遇到一个label的坑,点击label的时候,监听的click事件被执行两次;

具体代码如下:

   <div id="test">
  <input type="checkbox" name="abc" id="abc"/>
  <label for="abc">3423432432432432</label>
  </div>
  <script type="text/javascript">
  document.getElementById("test").onclick = function(ev) {
  console.log(ev.target);
  }
  </script>

在控制台我们可以看到:

触发的事件源分别为input和label;

触发条件很简单:

  1、监听的是label和input的上层元素click事件

  2、label和input关联(for或者input在label下)

问题原因::

点击label的时候,事件冒泡一次,同时会触发关联的input的click事件,导致事件再次冒泡

解决方案:

  1、不用label(最简单直接粗暴的方法),如果为了语义化或者是个人习惯又不得不用label标签,那就继续往下看

  2、咱只认input,判断事件源为input,具体代码如下:

     document.getElementById("test").onclick = function(e) {
var ev = e || window.event;
var elm = ev.target || ev.srcElement;
if (elm.tagName === 'LABEL') {return;}
// do something;
}

  上面代码受场景限制,即当input和label不关联的时候,点击label不作处理就会出现新的bug,所以改进如下:

     /**
* 是否包含某id的input后代元素
* @param {Element} elm 要判断的元素
* @param {String} id 要匹配的id
* @return {Boolean}
*/
function hasInput(elm, id) {
for (var i = 0, inputs = elm.getElementsByTagName("input"), len = inputs.length; i < len; i++) {
if (inputs[i].id === id) {return true;}
}
return false;
}
/**
* 判断某元素下的label是否有关联的input
* @param {Element} elm 要判断的元素
* @param {Element} label label元素
* @return {Boolean}
*/
function isLabelhasRelativeInput(elm, label) {
if (label.getElementsByTagName("input").length) {
return true;
}
var forT = label.getAttribute("for");
var isIE6 = !-[1,] && !window.XMLHttpRequest;// IE6不支持for属性
if (forT && hasInput(elm, forT) && !isIE6) {
return true;
}
return false;
}
document.getElementById("test").onclick = function(e) {
var ev = e || window.event;
var srcElm = ev.target || ev.srcElement;
if (srcElm.tagName === 'LABEL' && isLabelhasRelativeInput(this, srcElm)) {return;}
// do something;
}

  顿时不开心了,代码变的这么长,修正了上述问题,通用性会更强一些了

3:祭出终极解决方案

     var evTimeStamp = 0;
document.getElementById("test").onclick = function(e) {
var now = +new Date();
if (now - evTimeStamp < 100) {
return;
}
evTimeStamp = now;
console.log(2);
}

  通过事件触发的时间戳来判断,其实和事件冒泡有关的问题都可以通过该方法去处理。安全无公害

  最后给大家推荐下我们的群: ,无水js技术群,欢迎热爱前端的朋友加入

点击label时click事件被触发两次的坑的更多相关文章

  1. jquery给label绑定click事件被触发两次解决方案

    首先我们看下面的代码片段(label包裹checkbox) <div class="example"><label for="chk_6" c ...

  2. label标签内含有input元素,点击事件会触发两次

    **label标签内含有input元素,点击事件会触发两次** 如果你的结构是label内写input实现点击文字时候input也有相应.并且,把事件设置在了label上,那么就会执行两次了. //h ...

  3. 当一个HTML元素需要添加mouseon、mouseout与click事件,或者mouserenter、mouseleave和click事件时,click事件无法触发

    当一个HTML元素需要添加mouseon.mouseout与click事件,或者mouserenter.mouseleave和click事件时,click事件无法触发 针对上述问题,我遇到的有两种情况 ...

  4. iphone上click事件不触发的问题解决。

    iphone上click事件不触发的问题解决. //在ID为jsProvince上有这么一个事件: $('body').on('click', '#jsProvince', function(e){ ...

  5. EasyUi中的datagird中a标签的click事件无法触发?(已解决)

    ***************************2015-10-29 21:07************************* 问题如下: datagrid最后一列编辑中有如下a标签 { f ...

  6. 移动端的click事件延迟触发的原理是什么?如何解决这个问题?

    移动端的click事件延迟触发的原理是什么?如何解决这个问题? 原理 :移动端屏幕双击会缩放页面 300ms延迟 会出现点透现象 在列表页面上创建一个弹出层,弹出层有个关闭的按钮,你点了这个按钮关闭弹 ...

  7. 如何用按钮的click事件去触发a标签的click事件

    在jQquery中,可以用如下方式触发input.a标签的click事件: <input id="my_input" /> <a id="my_a&qu ...

  8. ie6下a标签click事件无法触发加载iframe

    ie6下a标签click事件无法触发加载iframe,把a换成span或者别的,就可以了

  9. jquery 动态生成html后click事件不触发原因

    转自:http://www.iam3y.com/html/560.html 最近在做一个项目的时候,遇到动态加载微博内容,然后点击“展开评论”后获取该微博的所有评论.这里使用了动态加载的<spa ...

随机推荐

  1. 信息安全系统设计基础实验四:外设驱动程序设计 20135211李行之&20135216刘蔚然

    北京电子科技学院(BESTI) 实 验 报 告 封面 课程:信息安全系统设计基础                                           班级:1352           ...

  2. ccpc-1008-HDU5839Special Tetrahedron-计算几何

    计算几何水题.暴力搞 注意力全部都在02那里,完全没想这道题! /*------------------------------------------------------------------ ...

  3. (转)Python实例手册

    原文地址:http://hi.baidu.com/quanzhou722/item/cf4471f8e23d3149932af2a7 实在是太好的资料了,不得不转 python实例手册 #encodi ...

  4. 用Canvas玩3D:点-线-面

    声明:本文为原创文章,如需转载,请注明来源WAxes,谢谢! 玩Canvas玩了有两三个礼拜了,平面的东西玩来玩去也就那样,所以就开始折腾3D了. 因为Canvas画布终究还是平面的,所以要有3D就得 ...

  5. Unity3D 文字滚动跑马灯效果

    需求 在日常游戏中,文字滚动效果是比较常用的.例如日常游戏顶部的新闻公告,聊天系统的文字滚动,都属于这个范围. 思路 由于使用的地方比较广泛,所以希望能够尽量独立的游戏之外,能够做到随处使用的功能.N ...

  6. WINDOWS8.1安装ORACLE客户端及配置

    1.官方网站下载: instantclient-basic-win32-11.2.0.1.0.zip instantclient-sqlplus-win32-11.2.0.1.0.zip instan ...

  7. 微信小程序开发公测,小程序账号申请办法攻略

    11月3号晚上 10 点,微信公众平台发布公告,宣布微信小程序正式开放公测.此次小程序公测允许开发者将产品提交至微信公众平台审核,但是暂时不支持发布,也就是说普通消费者若想体验小程序,还需要等待一段时 ...

  8. Android数据共享

    Android数据共享 在Android应用程序开发的过程中,借助Bundle类对象来传递数据并不是在所有场景下都适用,就那简单的Intent类对象来说,就不能put进Bundle类对象中.当然不能否 ...

  9. 深入javascript

    1.不定参数的使用 <!DOCTYPE html> <html> <head> <title>json</title> <script ...

  10. DOM(四)事件流

    1.冒泡型事件 浏览器的事件模型分两种:捕获型事件和冒泡型事件.由于ie不支持捕获型事件,所以以下主要以冒泡型事件作为讲解.(dubbed bubbling)冒泡型指事件安装最特定的事件到最不特定的事 ...