点击label时click事件被触发两次的坑
今天帮群里的朋友看一段代码的时候偶然间遇到一个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事件被触发两次的坑的更多相关文章
- jquery给label绑定click事件被触发两次解决方案
首先我们看下面的代码片段(label包裹checkbox) <div class="example"><label for="chk_6" c ...
- label标签内含有input元素,点击事件会触发两次
**label标签内含有input元素,点击事件会触发两次** 如果你的结构是label内写input实现点击文字时候input也有相应.并且,把事件设置在了label上,那么就会执行两次了. //h ...
- 当一个HTML元素需要添加mouseon、mouseout与click事件,或者mouserenter、mouseleave和click事件时,click事件无法触发
当一个HTML元素需要添加mouseon.mouseout与click事件,或者mouserenter.mouseleave和click事件时,click事件无法触发 针对上述问题,我遇到的有两种情况 ...
- iphone上click事件不触发的问题解决。
iphone上click事件不触发的问题解决. //在ID为jsProvince上有这么一个事件: $('body').on('click', '#jsProvince', function(e){ ...
- EasyUi中的datagird中a标签的click事件无法触发?(已解决)
***************************2015-10-29 21:07************************* 问题如下: datagrid最后一列编辑中有如下a标签 { f ...
- 移动端的click事件延迟触发的原理是什么?如何解决这个问题?
移动端的click事件延迟触发的原理是什么?如何解决这个问题? 原理 :移动端屏幕双击会缩放页面 300ms延迟 会出现点透现象 在列表页面上创建一个弹出层,弹出层有个关闭的按钮,你点了这个按钮关闭弹 ...
- 如何用按钮的click事件去触发a标签的click事件
在jQquery中,可以用如下方式触发input.a标签的click事件: <input id="my_input" /> <a id="my_a&qu ...
- ie6下a标签click事件无法触发加载iframe
ie6下a标签click事件无法触发加载iframe,把a换成span或者别的,就可以了
- jquery 动态生成html后click事件不触发原因
转自:http://www.iam3y.com/html/560.html 最近在做一个项目的时候,遇到动态加载微博内容,然后点击“展开评论”后获取该微博的所有评论.这里使用了动态加载的<spa ...
随机推荐
- 访问图片可以使用闭包map
1 imageView.animationImages = [ UIImage(named:"panda1"), UIImage(named:"panda2") ...
- CUDA编程学习(一)
/****c code****/ #include<stdio.h> int main() { printf("Hello world!\n); ; } /****CUDA co ...
- 【android】TabLayout文字闪烁问题
安卓MD设计提供了一个非常酷炫的效果,TabLayout拿来做选项卡时非常合适的,但是在实际使用中发现22.2.1版本号的TabLayout在ViewPager滑动的时候会出现闪烁现象. 解决方法:在 ...
- 开源分布式实时计算引擎 Iveely Computing 之 WordCount 详解(3)
WordCount是很多分布式计算中,最常用的例子,例如Hadoop.Storm,Iveely Computing也不例外.明白了WordCount在Iveely Computing上的运行原理,就很 ...
- Bootstrap系列 -- 24. 下拉菜单基本用法
在使用Bootstrap框架的下拉菜单时,必须调用Bootstrap框架提供的bootstrap.js文件.当然,如果你使用的是未编译版本,在js文件夹下你能找到一个名为“dropdown.js”的文 ...
- IE10访问apache 2.4会奇慢的解决办法
Windows版的apache 2.4. IE10访问apache 2.4会特别慢.有时Apache挂起了.只好重新开apache,但是重开后,也会好景不长,刚处理几个请求,就又变得奇慢了.Firef ...
- AngularJS - 路由入门
我们有很多方法让一个视图随着用户的操作进行变化. 但是,只是单单一个视图就要满足所有的需求会让代码变得非常复杂. 也许我们可以使用ng-include来引用各种模板,但这只限于部分场景. 于是我们可以 ...
- javascript 重难点(原型链 this) 理解总有一个过程,不要急,循序渐进!
开始补充: 1. 将函数定义作为对象的属性,称之为对象方法.2. this的指向是由它所在函数调用的上下文决定的(语境),而不是由它所在函数定义的上下文决定的.3. 因为当一个函数作为函数而不是方法来 ...
- CSS3媒体查询
随着响应式设计模型的诞生,Web网站又要发生翻天腹地的改革浪潮,可能有些人会觉得在国内IE6用户居高不下的情况下,这些新的技术还不会广泛的蔓延下去,那你就错了,如今淘宝,凡客,携程等等公司都已经在大胆 ...
- 【UESTC 482】Charitable Exchange(优先队列+bfs)
给你n个物品交换,每个交换用r,v,t描述,代表需要用r元的东西花费t时间交换得v元的东西.一开始只有1元的东西,让你求出交换到价值至少为m的最少时间代价.相当于每个交换是一条边,时间为边权,求走到价 ...