微信小程序-slider模块-双向滑动

这里是改良的slider滑块,实现双向滑动,也是一个代码的存储
已0点到24点的时间范围选择为例
这是wxml页面

<view class='buyMian-slide'>
    <view class='flex flexSb buyMian-slide-range'>
      <!-- <view class=''>{{min}}点</view> -->
      <!-- <view class=''>{{max}}点</view> -->
    </view>
    <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>
      <view wx:if='{{closeToFlag}}' class="show-merge-content" style="left:{{closeToPosition+'%'}}"><text>{{slider1Value}}点 - {{slider2Value}}点</text></view>
    </view>
    <view class='buyMian-slide-contain'  wx:if="{{choose==1}}">
      <slider wx:if='{{!change2}}' block-color="#fd7373" style='width:{{slider1W+"%"}};z-index:{{zIndexFlag==1?1:3}}' class='slider-left' block-size="10" value="{{slider1Value}}" min='{{min}}' max='{{slider1Max}}' backgroundColor='#fd7373' activeColor='#f7f7f7' bindchanging='changing' catchtouchstart='changeStart' bindchange='changed' data-idx='1'></slider>
      <slider wx:if='{{!change}}' block-color="#fd7373" style='width:{{slider2W+"%"}};z-index:{{zIndexFlag==2?1:3}}' class='slider-right' block-size="10" value="{{slider2Value}}" min='{{slider2Min}}' max='{{max}}' backgroundColor='#f7f7f7' activeColor='#fd7373' bindchanging='changing' catchtouchstart='changeStart' bindchange='changed' data-idx='2'></slider>
    </view>

  </view>

这里是wxss页面

.buyMian-slide{
  width: 654rpx;
  margin: 0 auto;
  height: 120rpx;
  box-sizing: border-box;
}
 
.buyMian-title {
  width: 654rpx;
  margin: 0 auto;
  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;
  position: relative;
  /* left: -25rpx; */
  /* background: red; */
}
 
.buyMian-slide-range {
  width: 100%;
  height: 50rpx;
  line-height: 50rpx;
  font-size: 26rpx;
  color: #8a8a8a;
  justify-content: space-around;
}
.slider-left, .slider-right {
  /* margin-right: -8rpx; */
  margin: 0;
}
.showContentBox{
  width: 100%;
  margin: 0 auto;
  height: 36rpx;
  /* background: blue; */
  /* position: absolute; */
  top: 10rpx;
  position: relative;
  /* 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%;
  height: 30rpx;
  line-height: 30rpx;
  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;
}

这里是js

var util = require('../../../utils/util.js');
Page({
 
  /**
   * 页面的初始数据
   */
  data: {
    change: false, // 当两个slider在最右端重合时,将change设置为true,从而隐藏slider2,才能继续操作slider1
    change2: false, // 当两个slider在最左端重合时,将change2设置为true,从而隐藏slider1,才能继续操作slider2
    max: 24, // 两个slider所能达到的最大值
    min: 0, // 两个slider所能取的最小值
    rate: 24/100, // slider的最大最小值之差和100(或1000)之间的比率 即最大值-最小值/100
    slider1Max: 24, // slider1的最大取值
    slider1Value: 0, // slider1的值
    slider2Value: 1, // slider2的值
    slider2Min: 0, // slider2的最小取值
    slider1W: 0, // slider1的宽度
    slider2W: 100, // slider2的宽度
    showContent1: 0, //左边滑块离左边的距离
    showContent2: 100/24, //右边滑块离左边的距离
    zIndexFlag: 1, //控制层叠
    closeTo: 1,//靠近多少就合并数字 百分比
    closeToFlag: false,//true时 合并数字
    closeToPosition: 0,//合并数字的位置
  },
  onLoad: function (options) {
    let list = []
    for(let i=0;i<24;i++){
      list.push(i+'点-'+(i+1)+'点');
    }
    this.setData({
      list: list
    })
  
  },

  // 开始滑动
  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;
      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;
      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 - ((this.data.max - this.data.slider1Value) / this.data.rate)
      })
    } else if (idx === 2) {
      this.setData({
        slider2Value: value,
        showContent2: 100 - ((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 - ((this.data.max - this.data.slider1Value) / this.data.rate)
      })
    } else if (idx === 2) {
      this.setData({
        showContent2: 100 - ((this.data.max - this.data.slider2Value) / this.data.rate)
      })
    }
    if (this.data.slider1Value === this.data.slider2Value && this.data.slider2Value === this.data.max) {
      this.setData({
        change: true
      })
    }
    if (this.data.slider1Value === this.data.slider2Value && this.data.slider2Value === this.data.min) {
      this.setData({
        change2: true
      })
    }
    this.drawCanvas();
  }
})

实现的核心思想在于两个slider的位置拼接,slider1显示的值永远是0,但是slider2展示出来的数据永远是最中心的值,看看change触发的变化就能懂。

在这里申明一下,灵感来自于:

https://blog.csdn.net/Hero_rong/article/details/101057530

然后参考了:

https://blog.csdn.net/weixin_45154833/article/details/104814508

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用微信小程序的 `slider` 组件和 `image` 组件来实现双向 slider 加背景图展示的效果。 首先,需要在 `wxml` 文件中添加 `slider` 和 `image` 组件,代码如下: ```html <view class="container"> <image class="background" src="{{backgroundUrl}}"></image> <slider class="slider" value="{{value1}}" min="{{min}}" max="{{max}}" bindchange="onChange"></slider> <slider class="slider" value="{{value2}}" min="{{min}}" max="{{max}}" bindchange="onChange"></slider> </view> ``` 其中 `background` 类设置背景图的样式,`slider` 类设置 slider 的样式。 然后,在 `js` 文件中定义 `data`,并在 `onLoad` 函数中设置背景图: ```javascript Page({ data: { backgroundUrl: '/images/background.jpg', value1: 20, value2: 80, min: 0, max: 100, }, onLoad: function () { wx.getImageInfo({ src: this.data.backgroundUrl, success: (res) => { this.setData({ backgroundWidth: res.width, backgroundHeight: res.height, }) }, }) }, onChange: function (event) { const { value } = event.detail const { dataset } = event.currentTarget const { index } = dataset if (index === '1') { this.setData({ value1: value, }) } else { this.setData({ value2: value, }) } }, }) ``` 在 `onChange` 函数中,通过 `dataset` 获取 slider 的索引,然后根据索引更新对应的 `value`。 最后,在 `wxss` 文件中设置样式: ```css .container { position: relative; } .background { position: absolute; top: 0; left: 0; width: 100%; height: 100%; z-index: -1; } .slider { position: absolute; width: 80%; left: 10%; z-index: 1; } ``` 其中,`background` 样式设置背景图的样式,`slider` 样式设置 slider 的样式,并通过 `z-index` 属性设置层级关系,保证 slider 在背景图上方。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值