不使用插件与组件库 - 如何简单实现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