Label 和 checkbox 不为人知的小秘密
最近开发的时候同事遇见了一个问题,点击label的时候改变checkbox的属性,或许大家觉得这是一个很简单的问题,然而这里面却蕴藏着一个大坑!
举例说明:
页面简单,就是一个
<input id="input" type="checkbox">
和一个
<label id="label" for="t">点我</label>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<div>
<input id="input" type="checkbox"> <label id="label" for="input">点我</label>
</div>
</body>
操作的思路大致是点击给label添加一个事件,通过判断checkbox当前的状况来改变checkbox的状态,代码如下:
<script>
var inputELe = document.getElementById('input'); //input元素
var labelEle = document.getElementById('label'); //label元素
labelEle.addEventListener('click',function(e){ //给label添加事件
alert('我被点了');
if(inputELe.checked){ //如果当前是选中状态
inputELe.checked = false //置为false
}else{
inputELe.checked = true //否则置为true
}
});
</script>
乍一看代码很完美,完全能够满足要求,但是实际上呢?看gif图:

可以看到,无论我怎么点击,checkbox都没有变成选中状态。这是一个很奇怪的现象。要解释这个现象要知道label和这个input之间的通信问题。
点击label触发checkbox状态改变和直接点击checkbox触发改变的过程是不一样的,
直接点击checkbox会立即改变checkbox的状态,如下:
假如现在代码如下:
inputELe.addEventListener('click',function(e){ //只给input元素添加事件
alert(inputELe.checked);
});

可以看到,当input的状态在视图上还没改变的时候,他的checked的值已经发生了改变了,而如果在label上加事件呢?
labelEle.addEventListener('click',function(e){
alert(inputELe.checked);
});

这样则在点击label的时候,并没有立刻改变checkedbox的状态,而是当注册在label上的事件alert完了之后,才改变的checkbox的状态。造成这种现象的原因在于:
点击label的时候,label有限处理自己对应的事件,然后再通知checkbox改变状态,而且,只会通知checkbox改变状态,并不告诉他要改变成true还是false,checkbox当前是true就变成false,是false就改成true.
这样便可以理解一开始的程序为什么没有改变成功状态了。
再把代码拷过来,一步一步看,假设一开始checkbox没有选中:
labelEle.addEventListener('click',function(e){ //给label添加事件
alert('我被点了');
if(inputELe.checked){ //由于点击label的时候,还没有告诉checkbo改变状态,所以当前值是false,执行else语句
inputELe.checked = false //置为false
}else{
inputELe.checked = true //所以这个时候checkbox应该变成了true,状态改变成功!
}
});
上面的方法确实改变了checkbox的状态但是,执行完这个方法后,label还有事要做,那就是通知checkbox改变状态,由于这时候执行的方法里面已经把checkbox的状态改成了true,所以当checkbox接到label的消息的时候,又会把自己变成false,
所以改变状态并没有成功,一来一回又被变成了原样了。checkbox一开始为false的时候也一样。
所以当大家使用label和checkbox(radio也一样)组合的时候,一定注意:不要把事件加给label,却在点击时间里去改变checkbox的状态!正确的做法是始终给checkbox添加事件并且改变checkbox的状态。
最后,告诉大家这个组合的使用场景:
就是组合成一个这样的开关,通过隐藏input并给label添加样式:after 和 :before 伪元素即可,当然注意操作的时候不要陷入上面的坑里面。
Label 和 checkbox 不为人知的小秘密的更多相关文章
- label联动checkbox
label联动checkbox时,若label包含在checkbox外层时label不需for属性,设置label的display属性为block时可以使整个div联动.
- html中的label配合checkbox,redio用法
<input id="a1" type="checkbox" name="a" value="33023" /&g ...
- Java不为人知的小秘密
Java中的main方法必须有一个外壳类,而且必须是静态的! Java中的所有函数都属于某个类的方法,所以main方法也不例外,必须放在一个类中才能编译运行. 例如: public class tex ...
- 多个 label checkbox 组合 显示在同一个水平线上[前提Bootstrap框架]
<th align="left" valign="middle"> <label class="checkbox inline fo ...
- React中 checkbox 与 label 标签的搭配
用<label>标签替代checkbox的点击样子,点击<label>实际上就是点击checkbox checkbox的checked值会跟着一起变 <input typ ...
- 巧用CSS3伪类选择器自定义checkbox和radio的样式
由于原生的checkbox和radio的样式太简陋了,在设计页面的时候,设计师往往会设计自己的checkbox和radio样式.一半情况下,为了适应各个浏览器的兼容性,我们都会用其他的元素替代原生的c ...
- jquery mobile radio,checkbox button 样式设置
<label><input type=checkbox ></label>,<input type=checkbox id="checkbox &q ...
- 使用CSS3美化复选框checkbox
我们知道HTML默认的复选框样式十分简陋,而以图片代替复选框的美化方式会给页面表单的处理带来麻烦,那么本文将结合实例带您一起了解一下使用CSS3将复选框checkbox进行样式美化,并且带上超酷的滑动 ...
- linux下so动态库一些不为人知的秘密
linux 下有动态库和静态库,动态库以.so为扩展名,静态库以.a为扩展名.二者都使用广泛.本文主要讲动态库方面知识. 基本上每一个linux 程序都至少会有一个动态库,查看某个程序使用了那些 ...
随机推荐
- Apriori算法的C++实现
Apriori是经典的购物篮分析算法.该算法用SQL实现难度较大,所以考虑用C++实现. 花了两天,代码例如以下.原创转载请注明出处 //Apriori.c #include<iostream& ...
- Javaproject集成log4j 2.x
log4j2和log4j在配置文件和引入jar包上出现了不同.这里做个备忘,这里使用的版本号为apache-log4j-2.3-bin.zip. 1.apache-log4j-2.3-bin.zip下 ...
- --------------Hibernate学习(四) 多对一映射 和 一对多映射
现实中有很多场景需要用到多对一或者一对多,比如上面这两个类图所展现出来的,一般情况下,一个部门会有多名员工,一名员工只在一个部门任职. 多对一关联映射 在上面的场景中,对于Employee来说,它跟D ...
- 八.利用springAMQP实现异步消息队列的日志管理
经过前段时间的学习和铺垫,已经对spring amqp有了大概的了解.俗话说学以致用,今天就利用springAMQP来完成一个日志管理模块.大概的需求是这样的:系统中有很多地方需要记录操作日志,比如登 ...
- 为什么在有的服务器上禅道、蝉知安装会报错? 之理解MySQL的SQL_MODE
最近用蝉知的CMS 建站比较多,感觉蛮顺手的,但在给客户安装的时候却会出现安装报错,其原因也很简单 查看了一下他们的install.sql文件中,有些时间字段的默认值是0000-00-00 00:00 ...
- 36、IO模型与socketserver实现并发
特别声明本随笔copy于egon(林海峰). 一 IO模型介绍 为了更好地了解IO模型,我们需要事先回顾下:同步.异步.阻塞.非阻塞 同步(synchronous) IO和异步(asynchronou ...
- iOS动态性:动态添加属性的方法——关联(e.g. 向Category添加属性)
想到要如何为所有的对象增加实例变量吗?我们知道,使用Category可以很方便地为现有的类增加方法,但却无法直接增加实例变量.不过从Mac OS X v10.6开始,系统提供了Associative ...
- Windows编程之进程遍历(C++实现)
Windows编程之进程遍历 PS: 主要扣代码使用,直接滑动到最下面使用. 遍历进程需要几个API,和一个结构体 1.创建进程快照 2.遍历首次进程 3.继续下次遍历 4.进程信息结构体 API 分 ...
- openstack操作之一 命令行
在openstack环境中提供了多种操作虚拟机的方法,有最简单直接的dashborad界面,有不直观但高效的命令行,还有进阶版的postman调用openstack restfulapi和命令行中使用 ...
- Web API系列之二WebApi基础框架搭建
本文主要介绍如何搭建一个WebApi的项目.关于如何搭建WebApi的方式一共有两种: 一.通过vs直接新建一个WebApi的项目,步骤如下: 第一步: 新建一个空的Web应用程序,可以理解为作为We ...