小程序原生的switch不能灵活的修改宽高、样式,很不方便,我这边参考WeUI的开关,写了一个可以自定义尺寸样式的switch组件。
直接上代码:https://gitee.com/piscdong/wechat-switch
效果如下图,可以自定义宽高,可以做成方角的
代码分析
这个switch主要的难点就是点击后背景颜色变换的动画,这里用到了css的transition、transform两个属性来实现动画,以及::before和::after两个伪元素。
wxml基本结构为:
<view class="switch">
<view></view>
</view>
父级view是整个switch容器,会用到::before做背景色切换动画,::after做禁用时的灰色遮罩。内部的一个view是来回切换的白点。未选中时默认class是switch,选中时增加一个class:switch_checked。
选中状态到未选中状态背景有一个从中间变大到全部的白色动画,所以需要给父级view设置一个颜色作为背景色。
.switch {
...
background: #00c000;
position: relative;
}
未选中时::before覆盖整个容器,选中时::before设置transform: scale(0);
,这样选中时白色区域就会缩放到最小,再加上transition实现动画效果。
.switch::before {
display: block;
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
border-radius: 9999rpx;
background: #fff;
transition: all 0.35s cubic-bezier(0.45, 1, 0.4, 1);
}
.switch_checked::before {
transform: scale(0);
}
来回移动的白点,未选中时通过left: 0;
定位到左侧,选中时将left设置为100%定位到右侧,但是这样白点会完全移出容器范围,所以还需要加上transform: translateX(-100%);
将白点向左再一定自身宽度的100%,同样加上transition实现动画效果。
.switch view {
position: absolute;
top: 0;
left: 0;
width: 60rpx;
height: 60rpx;
border-radius: 50%;
background: #fff;
box-shadow: 0 2rpx 6rpx rgba(0, 0, 0, 0.4);
transition: all 0.35s cubic-bezier(0.45, 1, 0.4, 1);
}
.switch_checked view {
left: 100%;
transform: translateX(-100%);
}
关于“::”
最后搭车说一下“:”和“::”,“:”是伪类,“::”是伪元素。按照我的理解:伪类不会在dom中增加节点,只不过是css选择器的一种特殊效果;伪元素会增加节点,flex布局中会影响到其他元素。
为了保证兼容性,css3是允许伪元素使用单个冒号。