今天帮群里的朋友看一段代码的时候偶然间遇到一个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技术群,欢迎热爱前端的朋友加入

最新文章

  1. CSS3边框图片属性---border-image
  2. JAVA程序提示错误:需要class,interface或enum解决方法
  3. win8下出现安装sql2012 正在启动操作系统功能"NetFx3"
  4. python 装 ez_setup.py 出错
  5. 通过在shell脚本中用scp或rsync实现远程同步文件
  6. Html5页面返回机制解决方案
  7. Oracle 10g创建表空间的完整步骤详解
  8. Prof UIS相关
  9. Ext布局篇
  10. Swift 控制流
  11. [SignalR]在非Hub继承类中使用脚本方法
  12. MySQL中函数、游标、事件、视图
  13. 字典破解zip
  14. 百度地图API-覆盖物
  15. 《.NET 设计规范》第 4 章:类型设计规范
  16. eclipse如何正确部署tomcat7
  17. 详解基于vue,vue-router, vuex以及addRoutes进行权限控制
  18. (二)Wireshark的实用表格
  19. hdu-2043解题报告
  20. 第八周(2) Word邮件合并1

热门文章

  1. Random()方法的使用
  2. 《信息安全系统设计基础》实验五 简单嵌入式WEB服务器实验
  3. 查询一个ID出现2种结果的情况
  4. 原生js dom记忆的内容
  5. jquery hasClass、removeClass、addClass方法
  6. Boostrap(2)
  7. 改善C#程序的建议3:在C#中选择正确的集合进行编码
  8. python 读写文件和设置文件的字符编码
  9. overlay-3
  10. poj2763 树链剖分(线段树)