关于美化复选框的一个小插曲!

   

有很多人都觉得浏览器自带的复选框、单选框的样式太丑,所以都会对它们进行美化处理,
我最近也这样做了,我是从网上找的一个现成的,但是在做的时候,遇到了一个小问题,这里有必要记录一下!
 
首先来说一下美化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 {
    cursorpointer;
    line-height20px;
    font-size15px;
}
.label_check input,.label_radio input {
    margin-right2px;
}
.has-js .label_check,.has-js .label_radio {
    padding-left18px;
}
.has-js .label_radio {
    backgroundurl(images/miniui/check3-off.png) no-repeat left center;
}
.has-js .label_check {
    backgroundurl(images/miniui/check3-off.png) no-repeat left center;
}
.has-js label.c_on {
    backgroundurl(images/miniui/check3-on.png) no-repeat left center;
}
.has-js label.r_on {
    backgroundurl(images/miniui/check3-on.png) no-repeat left center;
}
.has-js .label_check input,.has-js .label_radio input {
    positionabsolute;
    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 了两次,就等于是还原了,导制后台获取的值是没有变化的。
 
posted @ 2013-04-12 08:50  戴眼镜的码农  阅读(409)  评论(0编辑  收藏  举报