likes
comments
collection
share

不使用插件与组件库 - 如何简单实现switch开关组件这次与上次的不使用插件与组件库 - 如何简单实现滑动单元格肯定也

作者站长头像
站长
· 阅读数 19

前言

switch实现起来,主要利用了<input type="checkbox">标签与label标签合体。

准备

了解一下label与标签的用法

我们需要知道一些label的用法,首先温习一下label的用法

label主要:for 属性规定 label 与哪个表单元素绑定。

详见:HTML 标签的 for 属性

实现效果

  • 点击后拿到数据
  • 点击后圆球移动,背景改变

不使用插件与组件库 - 如何简单实现switch开关组件这次与上次的不使用插件与组件库 - 如何简单实现滑动单元格肯定也

实现思路

先给出HTML的结构

<input type="checkbox" id="switch" class="input-switch"/>
<label for="switch" class="label-switch" >
    <div class="ball"></div>
</label> 
  1. 使用label的属性for绑定了input,这样点击label与点击input就没有区别了,都能产生input checkbox的选中与取消的状态。

  2. 获取checkbox的状态,还是监听input中的改变,因为label只是一个展示,input才是改变产生的本质标签。

  3. label做出css样式渲染

以上,3步就完成了switch组件

input与label建立联系

就这样,inputidlable中的 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做支撑下,分别有以下方法:

元素有效属性是否占位
opacity0
visibilityhidden
transformscale(0)
displaynone
zoom0.0000....0001占位极小,可忽略
width0

注意: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()即可。

不使用插件与组件库 - 如何简单实现switch开关组件这次与上次的不使用插件与组件库 - 如何简单实现滑动单元格肯定也

转载自:https://juejin.cn/post/7137573201592205343
评论
请登录