为什么要做假单选框
很多时候我们想要一个有自己风格的单选框,但是html原生dom的input[radio]又平平无奇没有任何特点,最重要的是它不能修改样式,所以为了我们能够更随心意的去使用拥有更好看的样式的单选框,我们需要采用div+css的方式去做一个有单选框样子的东西出来。
首先,先做一个样子出来
我们先来看看一个正经的radio长什么样子
喏,就这个亚子,一点都不符合我们UI同学的审美,给我加颜色呀、给我加样式兄弟。
别慌,我们先来分析一下。一个正常的单选框都有一个作为背景的底板,还有一个显示是否被选中的状态内容物。因此,我们在制作的时候也就需要两层来进行显示。所以就简单的写两个父子div好了。
<div class="fRadio">
<div class="fRadio-in"></div>
</div>
光有空壳子也没用呀,它可显示不出来你想要的效果,所以我们还要给他加上样式css
.fRadio {
height: 50px;
width: 50px;
border-radius: 25px;
/* 将方形的盒子的四个角都设置成圆角
当圆角的px设置为高度和长度的一半的时候
它就变成一个规则的圆形啦 */
border: 4px solid rgb(235,235,235);
display: inline-block;
/* 将div这个块级元素转化为行内块级元素,方便我们进行操作 */
background-color: blue;
box-sizing: border-box;
/* 这个是一个很重要的东西
因为盒子模型的原因
当你改变一个盒子的padding以及border的时候
这个盒子的整体宽高会计算上你的border宽度以及padding的宽度
所以在加上4像素的border以后
本身盒子的宽度或者高度就达到了58px(两边都有border所以x2)
这样本身一开始规则的圆形就变成了半方的形状了
加上这个以后就可以搞定这个问题
使得盒子模型的高宽都以你一开始设定的高宽为基准
当然了margin不受影响 */
}
.fRadio-in {
/* 这个是内部容器
可以是图片,是文字,可以是符号,什么都行,
所以样式也就没有那么重要了 */
}
制作完成的样式大概长这个亚子
emmmm,边框颜色有点浅了,配色也有点丑,不过没关系,反正咱们是来讲道理的,就这样吧。
第二步,将你制作的样式和radio进行关联
现在我们做出来的也只是个静态的样式而已,和radio还没有一毛钱的关系,因此呢我们就需要通过js给他们强行添加关联了。
首先,我们得有一个radio,所以把我们的代码改造一下
<!-- 这里的this呢指代的就是这个div以及它内部的后代一切 -->
<div onclick="asd(this);"><div class="fRadio" name="fRadio">
<div class="fRadio-in" name="fRadioIn"></div>
</div>
<input type="radio" class="hidRadio" name="hidRadio" />
</div>
.hidRadio {
/* 加上这条当然是为了让它消失了
它只是个用来传值的工具而已
为了调试的时候观察方便
建议调试的时候还是把它放出来的好 */
display: none;
}
从代码上可以看到多出了name和onclick事件,为什么要加这些呢,当然是为了操作它呀,下面放出来js代码
/*byName或者byClass等获取的都不是一个值
而是一组,这里获取所有的name为fradioIn的元素
之所以用了byName其实是因为你的radio不可能只有一个鸭
我在这里其实写了三个来着,下边会放出 */
var fri = document.getElementsByName('fRadioIn');
//获取到真正的radio元素
var ccc = document.getElementsByName('hidRadio');
function asd(evt){
for(var i = 0; i < fri.length; i++){
fri[i].innerHTML = '';
/*
这个for的作用其实相当于是做一次初始化
每次在你点击的时候先将所有的假样式内的内容清除掉
*/
}
if(evt.children['hidRadio'].checked == false){
evt.children['hidRadio'].checked = true;
evt.children['fRadio'].children['fRadioIn'].innerHTML = '√';
/*
evt就是之前onclick里的this,也就是指代的是整个的div
evt.children['xxx']意思就是evt的某个名字叫xxx的子元素
这里判断hidRadio的checked的值
如果原本的checked值为false就将它设置为true
并在假radio的内部容器插入‘√’
*/
}else {
evt.children['hidRadio'].checked = false;
evt.children['fRadio'].children['fRadioIn'].innerHTML = ''
}
}
完整代码展示
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
.fRadio {
height: 50px;
width: 50px;
border-radius: 25px;
border: 4px solid rgb(235,235,235);
display: inline-block;
background-color: blue;
box-sizing: border-box;
}
.fRadio-in {
color: white;
}
.hidRadio {
/* display: none; */
}
</style>
</head>
<body>
<!-- 第一个 -->
<div onclick="asd(this);">
<div class="fRadio" name="fRadio">
<div class="fRadio-in" name="fRadioIn"></div>
</div>
<input type="radio" class="hidRadio" name="hidRadio" />
</div>
<!-- 第二个 -->
<div onclick="asd(this);">
<div class="fRadio" name="fRadio">
<div class="fRadio-in" name="fRadioIn"></div>
</div>
<input type="radio" name="hidRadio" />
</div>
<!-- 第三个 -->
<div onclick="asd(this);">
<div class="fRadio" name="fRadio">
<div class="fRadio-in" name="fRadioIn"></div>
</div>
<input type="radio" name="hidRadio" />
</div>
<button type="button" onclick="sdf()">提交</button>
<script type="text/javascript">
var fri = document.getElementsByName('fRadioIn');
var ccc = document.getElementsByName('hidRadio');
function asd(evt){
for(var i = 0; i < fri.length; i++){
fri[i].innerHTML = '';
}
if(evt.children['hidRadio'].checked == false){
evt.children['hidRadio'].checked = true;
evt.children['fRadio'].children['fRadioIn'].innerHTML = '1';
}else {
evt.children['hidRadio'].checked = false;
evt.children['fRadio'].children['fRadioIn'].innerHTML = ''
}
}
function sdf(){
var account = 0;
for(var i = 0; i < ccc.length; i++){
if(ccc[i].checked){
account++;
}
}
console.log(account)
}
</script>
</body>
</html>
这里说明一个大家可能都知道的东西,想要radio能达到互斥效果的话,只需要给他们取相同的name就可以了。这也是为什么还要绑定一个真的radio的原因。
总结
简单来说,其实就是用div+css做了一个样子而已,然后通过js将真的radio的checked值对相应的div进行了绑定。其实也可以不加radio直接通过js添加属性的方式去进行操作,可能稍微多一点步骤。
感谢观看!