有很多人都觉得浏览器自带的复选框、单选框的样式太丑,所以都会对它们进行美化处理,
我最近也这样做了,我是从网上找的一个现成的,但是在做的时候,遇到了一个小问题,这里有必要记录一下!
首先来说一下美化checkbox的大致思路
<label class="label_check" style="font-size:13px; float:left; margin-right:12px;" for="checkbox-04">
<input name="modules" id="checkbox-04" value="blog_catalog" type="checkbox" />文章分组</label>在checkbox外面包了一个 label 标签, 如果不加任何 css 和 js 的话,这样写与浏览器自带的样式是没有任何区别的,只是这种写法,点击文字的时候复选框也可以被选中。
截图为证:
开始美化,通过给 label 标签添加背景图,从而达到美化的效图,并为label绑定click事件在每次点击的时候,变换背景图 (选中/取消).
效果图如下:
下面直接上代码:
html代码:
<html>
<head>
<title>美化checkbox</title>
</head>
<body onload="init_check();">
<div id="choose">
<label class="label_check" style="font-size:13px; float:left; margin-right:12px;" for="checkbox-01">
<input name="modules" id="checkbox-01" value="checkbox-01" type="checkbox" checked/>博客LOGO</label>
<label class="label_check" style="font-size:13px; float:left; margin-right:12px;" for="checkbox-03">
<input name="modules" id="checkbox-03" value="checkbox-03" type="checkbox"/>文章分组</label>
<label class="label_check" style="font-size:13px; float:left; margin-right:12px;" for="checkbox-05">
<input name="modules" id="checkbox-05" value="checkbox-05" type="checkbox" checked/>最新文章</label>
<label class="label_check" style="font-size:13px; float:left; margin-right:12px;" for="checkbox-07">
<input name="modules" id="checkbox-07" value="checkbox-07" type="checkbox" checked/>最新回复</label>
</div>
</body>
</html>
注意 body 那里的 init_check(); 的作用是用来初使化checkbox样式的,如果不加checkbox就是浏览器默认的样式,不会有任何影响。css代码:
#choose label {
cursor: pointer;
line-height: 20px;
font-size: 15px;
}
.label_check input,.label_radio input {
margin-right: 2px;
}
.has-js .label_check,.has-js .label_radio {
padding-left: 18px;
}
.has-js .label_radio {
background: url(images/miniui/check3-off.png) no-repeat left center;
}
.has-js .label_check {
background: url(images/miniui/check3-off.png) no-repeat left center;
}
.has-js label.c_on {
background: url(images/miniui/check3-on.png) no-repeat left center;
}
.has-js label.r_on {
background: url(images/miniui/check3-on.png) no-repeat left center;
}
.has-js .label_check input,.has-js .label_radio input {
position: absolute;
left: -9999px;
}JS 代码:
//初使化复选框样式
//初使化复选框样式
var init_check = function() {
var body = getChild(document,'body')[0];
body.className = body.className && body.className != '' ? body.className + ' has-js' : 'has-js';
if (!document.getElementById || !document.createTextNode) return;
var ls = getChild(document,'label');
for (var i = 0; i < ls.length; i++) {
var l = ls[i];
if (l.className == 'label_check'){
var inp = getChild(l,'input')[0];
l.className = inp.checked ? 'label_check c_on' : 'label_check c_off';
//l.onclick = check_it; //为label绑定click事件
inp.onclick = check_it; //为checkbox绑定click事件
}
}
}; //获取当前对象的子对象
var getChild = function(parent,child) {
return parent.getElementsByTagName(child);
};
//复选框选择
var check_it = function() {
var la = this.parentNode;
if (la.className == 'label_check c_off') {
la.className = 'label_check c_on';
this.click();
} else {
la.className = 'label_check c_off';
this.click();
};
};
这里讲一下遇到的问题,以上的代码被我修改过很多(包括check_it),原本的click的事件是绑定在 label 上的,如下:
问题就出在这里,在测试的时候,我发现如果click事件绑定在label上的话, 点击的时候 check_it 函数会被触发多次,个人的理解如下:
这里 label 的 for 值与checkbox的id是一样的,所以这两个对象的click事件也被级联起来,
当人工点击 label 的时候会同时触发 label 和 checkbox, 而checkbox的onclick 事件会级联引发 label 的 click 事件,于是乎:
1. 人工点击 -----> label onclick -----> check_it;
2. 人工点击 -----> checkbox onclick ------> label onclick -------> check_it;
所以最后出现了这种情况,只看页面上的图片发生了变化.. 但是 checkbox 却 click 了两次,就等于是还原了,导制后台获取的值是没有变化的。