原文地址:複選框的一些事兒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事件就會冒泡了,又回到了前面說的問題。
關於樣式的深刻理解下一篇再學習研究,這裏就先到這兒了。
參考文章: