微信小程序双向slider

微信小程序双向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

相关推荐
©️2020 CSDN 皮肤主题: 深蓝海洋 设计师:CSDN官方博客 返回首页