微信小程序双向slider
最近因为项目要求,需要在微信小程序写一个双向slider,但是看到微信小程序是没有提供这个组件,只有单向slider的,所以自己写了一个。
本着面向搜索引擎编程的思想(开玩笑啦,别让领导看到哈哈哈),我在上看到很多大神的实现方式,大多数用catchtouchmove的去做,但是太麻烦了。还有说用ui框架的,但是如果什么都用别人的轮子,我们的编程思维会慢慢变迟钝的,直到看到一个用两个slider实现的文章。ps:我一开始也是想到用两个
废话不多说直接上代码
wxml代码
<!-- <view class='buyMian-title'>预算</view> -->
<view class='buyMian-slide'>
<!-- <view class='buyMian-slide-title'>{{min}}万-{{max}}万</view> -->
<view class='buyMian-slide-contain'>
<slider wx:if='{{!change2}}' style='width:{{slider1W+"%"}};z-index:{{zIndexFlag==1?1:3}}' class='slider-left' block-size="10" value="{{slider1Value}}" min='{{min}}' max='{{slider1Max}}' backgroundColor='#ff7500' activeColor='#f7f7f7' bindchanging='changing' catchtouchstart='changeStart' bindchange='changed' data-idx='1'></slider>
<slider wx:if='{{!change}}' style='width:{{slider2W+"%"}};z-index:{{zIndexFlag==2?1:3}}' class='slider-right' block-size="10" value="{{slider2Value}}" min='{{slider2Min}}' max='{{max}}' backgroundColor='#f7f7f7' activeColor='#ff7500' bindchanging='changing' catchtouchstart='changeStart' bindchange='changed' data-idx='2'></slider>
<view class="showContentBox">
<view wx:if='{{!change2 && !closeToFlag}}' class="show-min-content" style="left:{{showContent1+'%'}}"><text>{{slider1Value}}</text></view>
<view wx:if='{{!change && !closeToFlag}}' class="show-max-content" style="left:{{showContent2+'%'}}"><text>{{slider2Value}}</text></view>
<!-- 若是需要调整合并数字的盒子宽度 需要减去一半的margin -->
<view wx:if='{{closeToFlag}}' class="show-merge-content" style="left:{{closeToPosition+'%'}}"><text>{{slider1Value}}万 - {{slider2Value}}万</text></view>
</view>
</view>
<view class='flex flexSb buyMian-slide-range'>
<view class=''>{{slider1Value}}万</view>
<view class=''>{{slider2Value}}万</view>
</view>
</view>
wxss代码
.buyMian-slide, .buyMian-title {
width: 654rpx;
margin: 0 auto;
}
.buyMian-title {
font-size: 34rpx;
color: #212121;
line-height: 36rpx;
margin-top: 45rpx;
}
.buyMian-slide-title {
font-size: 36rpx;
color: #ff7500;
line-height: 38rpx;
margin-top: 25rpx;
text-align: center;
}
.buyMian-slide-slide {
margin: 10rpx auto 0;
}
/* range */
.buyMian-slide-contain {
width: 100%;
display: flex;
padding: 20px 0 10px;
position: relative;
/* left: -25rpx; */
/* background: red; */
}
.buyMian-slide-range {
font-size: 26rpx;
color: #8a8a8a;
margin-top: 15rpx;
}
.slider-left, .slider-right {
/* margin-right: -8rpx; */
margin: 0;
}
.showContentBox{
width: 100%;
height: 36rpx;
/* background: blue; */
position: absolute;
top: 0rpx;
/* left: 8rpx; */
}
.show-max-content,.show-min-content{
position: absolute;
width: 40rpx;
margin-left: -20rpx;
display: flex;
justify-content: center;
}
.show-max-content{
margin-right: -20rpx !important;
}
.show-min-content text{
position: absolute;
font-size: 26rpx;
}
.show-max-content text{
position: absolute;
font-size: 26rpx;
}
.show-merge-content{
position: absolute;
width: 40%;
display: flex;
justify-content: center;
margin-left: -20%;
}
.show-merge-content text{
position: absolute;
font-size: 26rpx;
width: 100%;
display: flex;
justify-content: center;
}
.flex {
display: -webkit-box;
display: -moz-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
display: box;
flex-wrap: wrap;
}
.flexSb {
justify-content: space-between;
-webkit-justify-content: space-between;
-moz-justify-content: space-between;
-ms-justify-content: space-between;
-o-justify-content: space-between;
}
js代码
Page({
/**
* 页面的初始数据
*/
data: {
change: false, // 当两个slider在最右端重合时,将change设置为true,从而隐藏slider2,才能继续操作slider1
change2: false, // 当两个slider在最左端重合时,将change2设置为true,从而隐藏slider1,才能继续操作slider2
max: 1000, // 两个slider所能达到的最大值
min: 50, // 两个slider所能取的最小值
rate: 9.5, // slider的最大最小值之差和100(或1000)之间的比率 即最大值-最小值/100
slider1Max: 1000, // slider1的最大取值
slider1Value: 50, // slider1的值
slider2Value: 1000, // slider2的值
slider2Min: 50, // slider2的最小取值
slider1W: 100, // slider1的宽度
slider2W: 0, // slider2的宽度
showContent1: 0, //左边滑块离左边的距离
showContent2: 100, //右边滑块离左边的距离
zIndexFlag: 1, //控制层叠
closeTo: 20,//靠近多少就合并数字 百分比
closeToFlag: false,//true时 合并数字
closeToPosition: 0,//合并数字的位置
},
// 开始滑动
changeStart: function (e) {
var idx = parseInt(e.currentTarget.dataset.idx)
if(this.data.slider1Value !== this.data.slider2Value){
this.setData({
change: false,
change2: false
})
}
if (idx === 1) {
// dW是当前操作的slider所能占据的最大宽度百分数
var dW = (this.data.slider2Value - this.data.min) / this.data.rate
console.log(dW)
this.setData({
slider1W: dW,
slider2W: 100 - dW,
slider1Max: this.data.slider2Value,
slider2Min: this.data.slider2Value,
zIndexFlag: 1,
change: false
})
} else if (idx === 2) {
var dw = (this.data.max - this.data.slider1Value) / this.data.rate
console.log(dw)
this.setData({
slider2W: dw,
slider1W: 100 - dw,
slider1Max: this.data.slider1Value,
slider2Min: this.data.slider1Value,
zIndexFlag: 2,
change2: false
})
}
},
// 正在滑动
changing: function (e) {
var idx = parseInt(e.currentTarget.dataset.idx)
var value = e.detail.value
if (idx === 1) {
this.setData({
slider1Value: value,
showContent1: 100 - parseInt((this.data.max - this.data.slider1Value) / this.data.rate)
})
} else if (idx === 2) {
this.setData({
slider2Value: value,
showContent2: 100 - parseInt((this.data.max - this.data.slider2Value) / this.data.rate)
})
}
// 当两个数字相近时 数字合并 太靠近两边会取一个足够显示的位置 15 85
if(this.data.showContent2 - this.data.showContent1 < this.data.closeTo){
let p = this.data.showContent1 + ((this.data.showContent2 - this.data.showContent1) / 2)
if(p > 85){
this.setData({
closeToFlag: true,
closeToPosition: 85
})
}else if(p < 15){
this.setData({
closeToFlag: true,
closeToPosition: 15
})
}else{
this.setData({
closeToFlag: true,
closeToPosition: p
})
}
}else{
this.setData({
closeToFlag: false
})
}
},
changed: function (e) {
let idx = parseInt(e.currentTarget.dataset.idx)
if (idx === 1) {
this.setData({
showContent1: 100 - parseInt((this.data.max - this.data.slider1Value) / this.data.rate)
})
} else if (idx === 2) {
this.setData({
showContent2: 100 - parseInt((this.data.max - this.data.slider2Value) / this.data.rate)
})
}
if (this.data.slider1Value === this.data.slider2Value && this.data.slider2Value === this.data.max) {
console.log(e)
this.setData({
change: true
})
}
if (this.data.slider1Value === this.data.slider2Value && this.data.slider2Value === this.data.min) {
this.setData({
change2: true
})
}
},
})
效果我也做了一些优化,合在一起时数字也会合并
第一次写文章,希望对你有用
https://blog.csdn.net/Hero_rong/article/details/101057530