原文地址:复选框的一些事儿javascript
对复选框总以为云里雾里,判断选中与未选中的方法总以为不明白,调整复选框与文字的对齐怎么调都没用,之前总没有动力去花一个真正的时间去解决这些问题,受到今天项目的启发,因此来弄清楚一下。html
一、先来讲说选中与未选中的方法与判断问题java
在表单中,jquery
1 <form action=""> 2 3 <input type="checkbox" id="test">复选框 4 5 </form> 6 7 <script> 8 $(function(){ 9 10 var test = $('#test').val(); 11 console.log(test); //on 12 13 }); 14 </script>
无论你选没选中,复选框的val都是on,因此确定是不能用这个来判断的。wordpress
在原生的js中,咱们能够用对象的checked属性,以下:学习
var test = document.getElementById('test').checked; console.log(test); //false
好比咱们用来点击事件发生时判断:this
1 <form action=""> 2 3 <input type="checkbox" id="test" onclick="check(this)">复选框 4 5 </form> 6 7 <script> 8 9 function check(obj){ 10 console.log(obj.checked); 11 } 12 </script>
你会发现你能够自由的判断是否选中了spa
但不少状况下咱们都是结合jquery来使用的,在jquery中,不少人都是使用的$().addAttr('checked', 'checked'); 给这个复选框的DOM添加checked属性,其实这个并无真正的选中复选框,来看个例子:.net
1 <form action=""> 2 3 <input type="checkbox" id="test2" checked onclick="check(this)">复选框2 4 5 </form> 6 7 <script> 8 function check(obj){ 9 console.log(obj.checked); 10 } 11 </script>
此时你会发现code
这里是咱们添加的checked属性,添加了这个属性,默认是选中的,也就是说,添加了checked属性后js对象的checked属性默认是选中的,咱们打印下:
var test = document.getElementById('test2').checked; console.log(test); //true
可是咱们点击复选框去掉选中的时候,DOM结构中的checked属性是不会被去掉的,但此时js对象的checked其实是等于false的。也就是说这并非一个可逆的过程,须要咱们手动移除attr为checked的属性。
但好比下种状况的时候
1 <ul> 2 <li style="background:#eee;"> 3 <input type="checkbox" id="test3"> 复选框3 4 </li> 5 </ul>
我想要实现的是点击li元素的文字就能够实现选中状态,固然点击复选框自己也能够实现选中状态,那么应该怎么作呢?
固然首先想到的确定是:
1 <ul> 2 <li style="background:#eee;" onclick="check3()"> 3 <input type="checkbox" id="test3"> 复选框3 4 </li> 5 </ul> 6 7 <script> 8 $(function(){ 9 10 var test3 = document.getElementById('test3'); 11 function check3(){ 12 if(test3.checked) 13 test3.checked = false; 14 else 15 test3.checked = true; 16 } 17 18 </script>
此时,你会发现点击li元素的确能够实现选中,可是,点击复选框自己就没有任何反应了,这是为何?为何?为何呢?
想一想就知道是事件冒泡的问题了,复选框自己在li元素中,li元素自己也会有点击事件,当你点击复选框时,它实际上是执行了的,但后来又执行了一次li元素的点击事件,致使复选框看起来没变化。
在这里咱们能够阻止默认事件的发生,打印结果:
var test3 = document.getElementById('test3'); function check3(){ if(test3.checked) test3.checked = false; else test3.checked = true; } $('#test3').click(function(event){ console.log(this.checked); event.stopPropagation(); });
在这里就要说说阻止默认事件和行为的3种方法的区别:(此处粘贴)
1.event.stopPropagation();
事件处理过程当中,阻止了事件冒泡,但不会阻击默认行为(它就执行了超连接的跳转)
2.return false;
事件处理过程当中,阻止了事件冒泡,也阻止了默认行为(好比刚才它就没有执行超连接的跳转)
3.event.preventDefault();
若是把它放在头部A标签的click事件中,点击“点击我”。
会发现它依次弹出:我是最里层---->我是中间层---->我是最外层,但最后却没有跳转到百度
它的做用是:事件处理过程当中,不阻击事件冒泡,但阻击默认行为(它只执行全部弹框,却没有执行超连接跳转)
这里就要来讲说jquery的prop()和attr()的区别,其实前面也提到过,this.checked 和 $(this).attr('checked')的区别,this指的是js对象,而$(this)指的是DOM对象,他们拥有的属性都是不同的,好比
<a id="a" href="ymblog.net"></a>
$(this).attr()属性就包含了id和href,而不包含style.width或者style.color,由于这些在js对象的style属性里面,
$('#a').click(function(){ console.log(this.id); //a console.log(this.href); //ymblog.net console.log($(this).style); //undefined });
说明this对象中包含了DOM对象的属性,反之则不是。
在这里的prop和attr也是同样的,区别就比如this.checked与$(this).attr('checked');同样。
详细能够参考这篇文章:jQuery中attr和prop方法的区别
了解完这2个属性之后,让咱们再来回顾前面的li元素中包裹的复选框的状况,在这里这样使用呢?
以下:
1 <ul> 2 <li style="background:#eee;" id="test4"> 3 <input type="checkbox" > 复选框4 4 </li> 5 </ul> 6 <a href="#" id="aaa">移除</a> 7 8 <script> 9 10 $('#test4').click(function(){ 11 $(this).find('input').attr('checked', 'checked'); 12 }) 13 $('#aaa').click(function(){ 14 $('#test4').find('input').removeAttr('checked'); 15 }); 16 </script>
若是你去运行,试过以后就会发现,第一次点击li元素,它会勾选,而后点击移除它会去掉勾选,这彷佛很正常啊,但当你第二次点击之后,它不勾选了,没反应了了,为何呢?
咱们能够来打印第一次点击之后的this.checked
$('#test4').click(function(){ $(this).find('input').attr('checked', 'checked'); console.log(document.getElementById('test5').checked); }) $('#aaa').click(function(){ $('#test4').find('input').removeAttr('checked'); console.log(document.getElementById('test5').checked); });
咱们每次都打印一下,下面是运行结果:
你会看到第一次点击之后,为input添加checked属性,this.checked = true;点击移除checked属性之后,this.checked = false;可是当第二次点击为input添加checked属性时,input却没有被勾选,也就是没有被checked。这是为何?谁能告诉我?为何?(待解决~)
在这里若是再用prop()checked一次,又会正常了,这也证实了前面的正确性
$('#test4').click(function(){ $(this).find('input').attr('checked', 'checked'); $(this).find('input').prop('checked', true); }) $('#aaa').click(function(){ $('#test4').find('input').removeAttr('checked'); $('#test4').find('input').prop('checked', false); });
在这里以为移除prop('checked',false);能够去掉,为何呢?
$('#test4').click(function(){ $(this).find('input').attr('checked', 'checked'); $(this).find('input').prop('checked', true); console.log(document.getElementById('test5').checked); }) $('#aaa').click(function(){ $('#test4').find('input').removeAttr('checked'); // $('#test4').find('input').prop('checked', false); console.log(document.getElementById('test5').checked); });
你会发现,不起做用的只有第二次点击选中的时候attr('checked', 'checked');而removeAttr('checked');每次都起到了checked = false;的做用。
在这里我彷佛不能彻底理解明白,有弄清楚的大神麻烦私信一份给我谢谢(472102644@qq.com)!
但咱们在这里的解决办法仍是有的,
好比上面的input复选框被包裹在一层li元素的状况下,你在为input添加checked属性之后,再为它的this对象的checked属性赋值为true,这样就确保了input真正的选中。
出现问题的根本缘由在于,你为input复选框(第一次是有效果的)添加checked属性之后,它并不会被checked,也就是说$(this).find('input')[0].checked == false;始终等于false。
也就是这段代码,感兴趣的能够去试试
1 <ul> 2 <li style="background:#eee;" id="test6"> 3 <input type="checkbox" id="input"> 复选框5 4 </li> 5 </ul> 6 7 <script> 8 $('#test6').click(function(){ 9 if( $(this).find('input').attr('checked') == 'checked'){ 10 $(this).find('input').removeAttr('checked'); 11 console.log($(this).find('input')[0].checked) 12 } 13 else{ 14 $(this).find('input').attr('checked',"checked"); 15 console.log($(this).find('input')[0].checked) 16 } 17 18 </script>
有人说,那你用prop判断不久能够了,你用prop后,点击input事件就会冒泡了,又回到了前面说的问题。
关于样式的深刻理解下一篇再学习研究,这里就先到这儿了。
参考文章: