最近开发的时候同事遇见了一个问题,点击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 不为人知的小秘密的更多相关文章

  1. label联动checkbox

    label联动checkbox时,若label包含在checkbox外层时label不需for属性,设置label的display属性为block时可以使整个div联动.

  2. html中的label配合checkbox,redio用法

    <input id="a1" type="checkbox" name="a" value="33023" /&g ...

  3. Java不为人知的小秘密

    Java中的main方法必须有一个外壳类,而且必须是静态的! Java中的所有函数都属于某个类的方法,所以main方法也不例外,必须放在一个类中才能编译运行. 例如: public class tex ...

  4. 多个 label checkbox 组合 显示在同一个水平线上[前提Bootstrap框架]

    <th align="left" valign="middle"> <label class="checkbox inline fo ...

  5. React中 checkbox 与 label 标签的搭配

    用<label>标签替代checkbox的点击样子,点击<label>实际上就是点击checkbox checkbox的checked值会跟着一起变 <input typ ...

  6. 巧用CSS3伪类选择器自定义checkbox和radio的样式

    由于原生的checkbox和radio的样式太简陋了,在设计页面的时候,设计师往往会设计自己的checkbox和radio样式.一半情况下,为了适应各个浏览器的兼容性,我们都会用其他的元素替代原生的c ...

  7. jquery mobile radio,checkbox button 样式设置

    <label><input type=checkbox ></label>,<input type=checkbox id="checkbox &q ...

  8. 使用CSS3美化复选框checkbox

    我们知道HTML默认的复选框样式十分简陋,而以图片代替复选框的美化方式会给页面表单的处理带来麻烦,那么本文将结合实例带您一起了解一下使用CSS3将复选框checkbox进行样式美化,并且带上超酷的滑动 ...

  9. linux下so动态库一些不为人知的秘密

    linux 下有动态库和静态库,动态库以.so为扩展名,静态库以.a为扩展名.二者都使用广泛.本文主要讲动态库方面知识.    基本上每一个linux 程序都至少会有一个动态库,查看某个程序使用了那些 ...

随机推荐

  1. Spring学习笔记(三)之装配Bean

    除了组件扫描与自动装配之外还有基于Java代码的装配与基于XML的装配. 有一些场景是我们不能用自动装配的,比如我们要给第三方库中的组件装配到我们的应用中,这时自动装配无效,因为自动装配只能扫描本应用 ...

  2. 原生JS的Ajax

    转自:https://www.cnblogs.com/yufann/p/JS-Ajax.html 1.创建一个Ajax对象 非IE6浏览器:var obj = new XMLHttpReuqest() ...

  3. 《金领简历:敲开苹果、微软、谷歌的大门》【PDF】下载

    <金领简历:敲开苹果.微软.谷歌的大门>[PDF]下载链接: https://u253469.ctfile.com/fs/253469-231196331 内容简介 <金领简历:敲开 ...

  4. sqlserver 存储过程 递归查询分组+hierarchyid重建会员关系

    CREATE PROCEDURE [dbo].[GetGroupInfo] @s_code NVARCHAR() = --会员卡号 AS BEGIN declare @p int; --查询唯一性结果 ...

  5. VMware的一些总结

    一.虚拟主机联网的三种方式: 1.仅主机(Host Only),虚拟主机只能与宿主机联网通信,无法访问外网和宿主机所在局域网的其它主机. 2.桥接(Bridge),在桥接模式下,虚拟主机就像是宿主机所 ...

  6. ABP PUT、DELETE请求错误405.0 - Method Not Allowed 因为使用了无效方法(HTTP 谓词) 引发客户端错误 No 'Access-Control-Allow-Origin' header is present on the requested resource

    先请检查是否是跨域配置问题,请参考博客:http://www.cnblogs.com/donaldtdz/p/7882225.html 一.问题描述 ABP angular前端部署后,查询,新增都没问 ...

  7. python链接mysql

    1.安装MySQLdb MySQLdb 是用于Python链接Mysql数据库的接口,它实现了 Python 数据库 API 规范 V2.0,基于 MySQL C API 上建立的. 下载地址: ht ...

  8. 5.Nginx作为web缓存服务器

    Nginx作为web缓存服务器 从0.7.48版本开始,Nginx支持类似Squid的缓存功能.Nginx的web缓存服务主要由proxy_cache相关命令集合fastcgi_cache相关命令集构 ...

  9. 字符串MD5加密运算

    public static string GetMd5String(string str)       {           MD5 md5 = MD5.Create();           by ...

  10. [E::hts_idx_push] NO_COOR reads not in a single block at the end 10 -1

    在分析转录组数据时,用bowtie2比对生成的bam文件,下一步call peak使用m6Aviewer,需要bam文件的index文件.所以我直接敲命令 samtools index xx.bam ...