今天帮群里的朋友看一段代码的时候偶然间遇到一个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. 20135220谈愈敏Blog6_进程的描述和创建

    进程的描述和创建 谈愈敏 原创作品转载请注明出处 <Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 进程 ...

  2. IOS开发之—— iOS 支付 [支付宝、银联、微信]

    支付宝iOSsdk官方下载sdk地址:https://b.alipay.com/order/productDetail.htm?productId=2013080604609654&tabId ...

  3. Stack around the variable 'szStr' was corrupted.

    错误:stack around the variable “XX” was corrupted.,中文翻译就是“在变量XX周围的堆栈已损坏”. 把 project->配置属性->c/c++ ...

  4. 程序员"青春饭"问题之我见

      程序员"青春饭"问题之我见 声明:转载请注明出处.http://www.cnblogs.com/hzg1981/ 1. 问题描述 问题1: 什么是程序员? 在本文中程序员的定义 ...

  5. 手把手教你Linux服务器集群部署.net网站 - Linux系统安装和设置

    在开源软件已成趋势化的今天,微软这‘老古董’也开始向开源方向发力,这对我们.NET开发者是极大的喜讯.而在开源软件中, Linux就是其中一个优秀的代表,几乎各行业和计算机有关的都有它的身影,其中一点 ...

  6. Unity3D 的摄像机

    什么是摄像机 Unity3D中,摄像机是一个非常非常重要的组件. 他的作用就是:将你设计的场景投影到设备的屏幕上. 摄像机的属性 1 clear flags 确定屏幕的哪一部分将被清除. 每个摄像机在 ...

  7. js的__proto__与propertype的关系

    经典的再也不能经典的一篇博客:http://www.cnblogs.com/snandy/archive/2012/09/01/2664134.html js中最propertype的一些方法的理解h ...

  8. [USACO2003][poj2018]Best Cow Fences(数形结合+单调队列维护)

    http://poj.org/problem?id=2018 此乃神题……详见04年集训队论文周源的,看了这个对斜率优化dp的理解也会好些. 分析: 我们要求的是{S[j]-s[i-1]}/{j-(i ...

  9. The first gui program by Qt

    #include<QApplication> #include<QPushButton> int main(int argc, char **argv) {     QAppl ...

  10. 网站性能工具Yslow的使用方法

    Yslow是雅虎开发的基于网页性能分析浏览器插件,从年初我使用了YSlow后,改变了博客模板大量冗余代码,不仅提升了网页的打开速度,这款插件还帮助我分析了不少其他网站的代码,之前我还特意写了提高网站速 ...