自定义单选框和多选框
Introduce
从公司回学校已经好几天了,翻翻看在公司做的某些东西,感慨良多。 平时学习的时候感觉自己这也很棒,那也很棒,实际上手时却是这也不会,那也不会,比如自定义一个单选框,都遇到很多的问题。所以专门抽时间做了一个比较丑陋的单选框和多选框。以备自己以后使用
简要原理
- 利用点击的时候切换不同的图片代替radio或者checkbox,实现选中或者去小时候的样式变化。比如你点击的时候出现✔️,取消的时候出现❎。
- 利用label标签和自定义的css样式。我用的是第二种实现方式。
主要原理
先讲一讲label吧,估计有很多人和我一样一脸懵逼。
label标签是为input标签标注的,是不会在页面显示任何特殊效果的。说白了,他就是提供你一个方法,让你把任意元素和input按钮关联,当我点击我关联的元素的时候就相当于我点击input标签。
一般来说,label标签主要是用来和checkbox或者radio关联的。
label关联的方式有两种,一种是显式关联,一种是隐式关联。
显式关联是通过label属性提供的for属性,需要注意的是,for属性的值必须是在与label标签在同一文档中的可标记表单元素的id,千万注意,是id,不是name,比如
性别: <input type = 'checkbox' name = '男' id = 'male'> <label for ='male'>男</label> <input type = 'checkbox' name ='女' id = 'female'> <label for = 'female'>女</label>
隐式关联是直接把表单空间放到label标签里,在这种情况下,label标签智能包含一个表单元素,如果包含多个那么只有一个有效,比如
<label>点击我你可以长高十厘米哦 <input type = 'text' name = 'handsome' id= 'goodlook>' </label>
既然有两种关联的方式,那么肯定就有好坏优缺点的区分了,我来大概形容一下吧
- 显示关联的优点,简绍标签嵌套的层次,在看别人的代码的时候,看他嵌套个五六层的真想砸电脑(砸他的),label标签可以不写在一个地方,input标签可以聚集写在一起,label也可以写在一起。
- 显示关联的缺点,你每次写input标签都需要多些一个id,而且你label和input不在一起,你写的时候是很自在的,但是如果后期维护,或者其余的人继续维护呢? 简直是痛苦。
- 隐式关联的优缺点和显式正好相反。
- 言归正传,实现原理就是
- 第一步是把input元素隐藏起来,用很多种方式,比如visibility设置为hidden,让别人看不到,或者使用opacity把透明度归0,或者你display :hidden也可以。实在不行 ,position: absolute让元素脱离文档流,然后给他z-inde设为负值,藏在所有元素的下面。
- 然后使用label标签的特点,在点击的时候实现input的选中或者取消
- 修改其余元素的样式,来实现你的需求
Tools
- 仍然强行推荐vscode,很快我会做一个插件的博客,方便大家安装下载。
- 谷歌浏览器调试,在之前的文章里,我有说过,如何使谷歌浏览器实现插件下载的功能
Code
html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>demo1</title> <link rel="stylesheet" href="./css/demo1.css"> </head> <body> <div class="content"> <div class="sex"> <div class="male active"> <label for="male">男 <input type="radio" id="male" name="sex" value="0"> </label> </div> <div class="female"> <label for="female">女 <input type="radio" id="female" name="sex" value="1"> </label> </div> </div> <div class="disable"> <label for="disabled">Disabled</label> <input type="radio" class="disabled" id="disabled" disabled> </div> <div class="checked active"> <label for="check"></label>Disabled&checked <input type="radio"> </div> <div class="many"> <label for="task1"> <div class="task1"> 女1 </div> </label> <input type="checkbox" id="task1"> <label for="task2"> <div class="task2"> 女2 </div> </label> <input type="checkbox" id="task2"> <label for="task3"> <div class="task3"> 女3 </div> </label> <input type="checkbox" id="task3"> </div> </div> <script src="./scripts/comoon.js"></script> <script src="./scripts/demo1.js"></script> </body> </html>
css
body { .content { width: 180px; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); .sex { width: 100%; height: 36px; position: relative; .male, .female { height: 34px; float: left; width: 83px; border: 2px solid #ccc; border-radius: 3px; cursor: pointer; position: relative; line-height: 34px; text-align: center; &:hover { border: 2px solid #0095ff; background-color: #ddd; position: relative; z-index: 333; } input { opacity: 0; // opacity: 1; position: absolute; } input[type="radio"]:checked { background: red; } } .active { background: url(../images/icon-right.png) no-repeat right bottom; z-index: 9999; border: 2px solid #0095ff; } .female { // background: green; margin-left: 6px; } } .disable { margin-top: 10px; width: 176px; height: 32px; border: 2px solid #ccc; text-align: center; line-height: 34px; cursor: default; color: #ccc; .disabled { opacity: 0; position: absolute; cursor: default; } } .active { background: url(../images/icon-right.png) no-repeat right bottom; z-index: 9999; border: 2px solid #0095ff; } .checked { margin-top: 10px; height: 32px; width: 176px; // border: 2px solid #ccc; text-align: center; line-height: 32px; input { opacity: 0; position: absolute; } } .many { .task1, .task2, .task3 { width: 176px; height: 32px; border: 2px solid #ccc; margin-top: 10px; text-align: center; line-height: 32px; &:hover { border: 2px solid #0095ff; } } input { opacity: 0; position: absolute; } } } }
common.js
'use strict'; // 判断dom节点是否含有某个类。 function hasClass(ele, cls) { cls = cls || ''; if (cls.replace(/\s/g, '').length === 0) { return false; } var clsArr = ele.className.split(/\s+/); var index = clsArr.indexOf(cls); if (index > 0) { return true; } else { return false; } } //删除某个类 function removeClass(ele, cls) { cls = cls || ''; if (cls.replace(/\s/g, '').length === 0) { return false; } var clsArr = ele.className.split(/\s/); var index = clsArr.indexOf(cls); if (index > 0) { clsArr.splice(index, 1); ele.className = clsArr.join(' '); } else { console.log(1); return false; } } function addClass(ele, cls) { if (hasClass(ele, cls)) { return false; } else { ele.className += ' ' + cls; return true; } }
demo1.js
'use strict'; /* global addClass removeClass */ // 取得所有有active类的节点,并删除这个类。 function resetActive() { var tag = document.getElementsByClassName('sex')[0]; tag = tag.getElementsByClassName('active'); var length = tag.length; for (var i = 0; i != length; i++) { removeClass(tag[i], 'active'); } } // 给性别加上绑定函数 function bindtag() { var male = document.getElementsByClassName('male')[0]; var female = document.getElementsByClassName('female')[0]; male.addEventListener("click", function () { resetActive(); addClass(male, 'active'); }); female.addEventListener("click", function () { resetActive(); addClass(female, 'active'); }); } bindtag(); // 检测容器下面所有选中的checkbox并取得他们的id,给他们同样id的容器加上active function addActive() { var tagparent = document.getElementsByClassName('many')[0]; var tag = tagparent.getElementsByTagName('input'); var length = tag.length; for (var i = 0; i != length; i++) { if (tag[i].checked === true) { var tagid = tag[i].id; var tagdom = document.getElementsByClassName(tagid)[0]; addClass(tagdom, 'active'); } else { var _tagid = tag[i].id; var _tagdom = document.getElementsByClassName(_tagid)[0]; removeClass(_tagdom, 'active'); } } } document.addEventListener('click', function () { addActive(); });
writer&contact
{
"name":"Jontyy" ,
"email": " jontyy@163.com"
}