复选框的一些事儿

原文地址:复选框的一些事儿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

7`S8L0M[KOSY86WSNR21QHN

 

但不少状况下咱们都是结合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

11

 

这里是咱们添加的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);
});

  

咱们每次都打印一下,下面是运行结果:

222

 

你会看到第一次点击之后,为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事件就会冒泡了,又回到了前面说的问题。

关于样式的深刻理解下一篇再学习研究,这里就先到这儿了。

参考文章:

jQuery中attr和prop方法的区别

checkbox复选框的一些深刻研究与理解

jquery 事件冒泡的介绍以及如何阻止事件冒泡

相关文章
相关标签/搜索