先贴一些测试目标代码吧
<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遍历,效率低,选择器越完整,查询速度一般越快
$("div.testdiv input:checkbox[name='checkbox1']").attr('checked',$isChecked);
2.这段代码是有bug,在jQuery中实现添加属性在底层显然使用了tag.setAttrbute(attrname,attrvalue);
而未直接使用tag.attrname=attrvalue;或者tag[attrname]=attrvalue。原因在于在非IE的浏览器内核阵营
推荐使用的是setAttribute,因为setAttribute可以添加非标签属性,所以造成片面上的属性添加而不是原
生属性的改变,特别是具有状态的标签,因此总成上面的切换只能发生一次。
代码改造:
先来说说原生js对象和jQuery对象的相互转换:
若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弥补了这种不足,添加了属性
prop(name|properties|key,value|fn)-->设置或者添加property
removeProp(name) -->移除property
$("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;
来源:oschina
链接:https://my.oschina.net/u/2256215/blog/341297