先贴一些测试目标代码吧java
<div class="testdiv" id='testdiv'> <label for="checkboxall"> <input type="checkbox" name="checkboxall" id="checkboxall" value="all"> 反选 </label> <p> <input type="checkbox" name="checkbox1">A <input type="checkbox" name="checkbox1"> B <input type="checkbox" name="checkbox1">C </p> <p> <input type="checkbox" name="checkbox1">D <input type="checkbox" name="checkbox1">E <input type="checkbox" name="checkbox1">F </p> </div>
再来一段BUG的代码:浏览器
$("div.testdiv label input:checkbox[name=checkboxall]").bind('change,click',function(evt){ var e = evt || window.event; $isChecked = $(this).attr("checked"); $("input:checkbox[name='checkbox1']").each(function(index,element){ $(this).attr("checked",$isChecked); }); });
错误分析:测试
首先这段代码写得不够简练,不必使用each遍历,效率低,选择器越完整,查询速度通常越快this
$("div.testdiv input:checkbox[name='checkbox1']").attr('checked',$isChecked);
2.这段代码是有bug,在jQuery中实现添加属性在底层显然使用了tag.setAttrbute(attrname,attrvalue);spa
而未直接使用tag.attrname=attrvalue;或者tag[attrname]=attrvalue。缘由在于在非IE的浏览器内核阵营code
推荐使用的是setAttribute,由于setAttribute能够添加非标签属性,因此形成片面上的属性添加而不是原对象
生属性的改变,特别是具备状态的标签,所以总成上面的切换只能发生一次。事件
代码改造:element
先来讲说原生js对象和jQuery对象的相互转换:rem
若element是js对象, js转为jQuery对象的方式$(element) jQuery转为js对象的方式$(element)[0]转为js对象(注意,集合对象不能这样转) 集合对象仍是用遍历方式比较好
jQuery方式改造以下:
$("div.testdiv label input:checkbox[name=checkboxall]").bind('change,click',function(evt){ var e = evt || window.event; //使用原生js获得当前“选择全部”标签的checked状态 $isChecked = this.checked; //这里不得不使用each遍历出全部符合条件的chekbox原生js对象 $("div.testdiv input:checkbox[name='checkbox1']").each(function(index,element){ element.checked = $isChecked;//或者 element['checked']=$isChecked; }); });
在js中不会出现这样的bug,在这里使用js实现一次吧
var $ = function(id) { return document.getElementById(id); } //添加事件兼容的方法 function addEvent(elm, evType, fn, useCapture) { if (elm.addEventListener) { elm.addEventListener(evType, fn, useCapture);//DOM2.0 return true; } else if (elm.attachEvent) { var r = elm.attachEvent('on' + evType, fn);//IE5+ return !!r; } else { elm['on' + evType] = fn;//DOM 0 } } var checkall = $('checkboxall'); var testdiv = $('testdiv'); var checkboxs = testdiv.getElementsByName('checkbox1'); function toggleCheckbox(evt) { var e = evt || window.event; for(var i=0;i<checkboxs.length;i++) { checkboxs[i]['checked'] = checkall.checked; //或者 checkboxs[i].checked = checkall.checked; } } addEvent(checkall,'click',toggleCheckbox,false); //最有一个参数设置为false,缘由一直没明白过,望读者自行检索相关信息,能够留言给我 addEvent(checkall,'change',toggleCheckbox,false);
好了,就这些了,注意测试时代码的执行顺序啊。
-----------------------------------------------------------------------------------
更新一下内容(2014-11-13)
在jQuery 1.6+版本以上,jQuery弥补了这种不足,添加了属性
$("input[type='checkbox']").prop({ disabled: true }); $("input[type='checkbox']").prop("disabled", false); $("input[type='checkbox']").prop("checked", true);
所以,全选能够改形成下面的方式
$("div.testdiv label input:checkbox[name=checkboxall]").bind('change,click',function(evt){ var e = evt || window.event; //使用原生js获得当前“选择全部”标签的checked状态 $isChecked = this.checked; //这里不得不使用each遍历出全部符合条件的chekbox原生js对象 $("div.testdiv input:checkbox[name='checkbox1']").prop('checked',true); });
这里要特别说明 property和attribute的雀斑,property指的是原生属性(特有),而arrtibute一般是共同属性和附加属性,
所以改变checked除了上述方法外,还能够使用这个。
Try doing it;