不使用插件与组件库 - 如何简单实现switch开关组件这次与上次的不使用插件与组件库 - 如何简单实现滑动单元格肯定也
前言
switch实现起来,主要利用了<input type="checkbox">标签与label标签合体。
准备
了解一下label与标签的用法
我们需要知道一些label的用法,首先温习一下label的用法
label主要:for 属性规定 label 与哪个表单元素绑定。
实现效果
- 点击后拿到数据
- 点击后圆球移动,背景改变

实现思路
先给出HTML的结构
<input type="checkbox" id="switch" class="input-switch"/>
<label for="switch" class="label-switch" >
<div class="ball"></div>
</label>
-
使用
label的属性for绑定了input,这样点击label与点击input就没有区别了,都能产生input checkbox的选中与取消的状态。 -
获取
checkbox的状态,还是监听input中的改变,因为label只是一个展示,input才是改变产生的本质标签。 -
对
label做出css样式渲染
以上,3步就完成了switch组件
input与label建立联系
就这样,input的id 与 lable中的 for字段一一对应。
<input type="checkbox" id="switch" class="input-switch"/>
<label for="switch" class="label-switch" >
<div class="ball"></div>
</label>
监听input的改变
注意:是获取input的DOM元素
let switchNode = document.querySelector("#switch");
switchNode.addEventListener("change", (e) => {
// 改变了要做点什么?
})
渲染css样式
1、要把原来的input的结点”隐藏”掉
再没有overflow: hidden做支撑下,分别有以下方法:
| 元素 | 有效属性 | 是否占位 |
|---|---|---|
| opacity | 0 | 是 |
| visibility | hidden | 是 |
| transform | scale(0) | 是 |
| display | none | 否 |
| zoom | 0.0000....0001 | 占位极小,可忽略 |
| width | 0 | 否 |
注意:zoom慎用,可能从在某些设备不兼容问题。
.input-switch{
/* 不让其input占位 */
display: none;
}
display:none是没有问题的,表单元素无法被点击并且消失,由于label绑定id,是可以使用label对input标签触发事件的。
2、对label的处理
label的css处理,需要使用到input checkbox的伪类:checked,表示被点击选中了,就能在选中伪类中,去实现背景颜色的变化与小球的移动。
小球的移动,是一种动画。
@keyframes onSwitch {
0% {
transform: translateX(0) scale(1);
}
100% {
transform: translateX(40px) scale(1);
}
}
@keyframes offSwitch {
0% {
transform: translateX(40px) scale(1);
}
100% {
transform: translateX(0) scale(1);
}
}
完整代码
HTML
<div class="title">变化</div>
<input type="checkbox" id="switch" class="input-switch"/>
<label for="switch" class="label-switch" >
<div class="ball"></div>
</label>
CSS
.input-switch{
/* 不让其input占位 */
display: none;
}
.label-switch{
display: inline-flex;
align-items: center;
cursor: pointer;
height: 40px;
width: 80px;
border-radius: 50px;
border: 2px solid rgb(185, 184, 184);
background-color: rgb(185, 184, 184);
}
/* input-switch:checked 就是选中的伪类*/
.input-switch:checked + .label-switch{
background-color: rgb(7, 114, 52);
border: 2px solid rgb(7, 114, 52);
}
.label-switch .ball{
height: 36px;
width: 36px;
border-radius: 50%;
background-color: rgb(255, 255, 255);
animation: offSwitch 0.25s ease-in forwards;
}
.input-switch:checked + .label-switch .ball{
animation: onSwitch 0.25s ease-in forwards;
}
@keyframes onSwitch {
0% {
transform: translateX(0);
}
100% {
transform: translateX(40px);
}
}
@keyframes offSwitch {
0% {
transform: translateX(40px);
}
100% {
transform: translateX(0);
}
}
JS
let titleNode = document.querySelector(".title");
let switchNode = document.querySelector("#switch");
switchNode.addEventListener("change", (e) => {
titleNode.innerText = e.target.checked
})
附加
感觉动画好像很无聊,设计自己的滚动速度?
试试这个:贝塞尔曲线_百度百科在CSS中使用做cubic-bezier() 函数,
你说你搞不懂,你就顺便填值上手试试。
transition: all 0.25s cubic-bezier(0.1, 0.7, 1.0, 0.1);
将以前的ease-in等,换成cubic-bezier()即可。

转载自:https://juejin.cn/post/7137573201592205343