微信小程序写一个可以左右拖拽滑动选择范围的组件

我们先上效果图
在这里插入图片描述
接着上代码
我们先在components文件夹里新建一个dragRange文件夹,文件夹里按照固定模式新建四个文件,分别是:dragRange.js、dragRange.json、dragRange.wxml、dragRange.wxss

下面是四个文件的代码

// dragRange.js

Component({
  properties:{
    points: Array,
    startIndex: {
      type: Number,
      default: 0,
    },
    endIndex: Number,
  },
  data:{
    easyMove: false,
    bodyInfo: {},
    progressActiveStyle: {
      left: 0,
      right: 0,
    },
    leftBtnInfo: {},
    rightBtnInfo: {},
    hightLightIndex: [],
    hightLightClass:[],
    hightLightIndexBackUp: [],
    bodyWidth: 0,
    step: 1,
    flag: false,

    stylePosition:{
      left: 'left:0px;',
      right: 'right:0px;',
      tenLeft: 'left:-10px;',
      tenRight: 'right:-10px;',
      leftAddRight: 'left:0px;right:0px;'
    }
  },
  observers:{
    "startIndex": function (nv,ov){
      if(!this.data.flag)this.init();
      this.setData({
        flag: true
      })
      console.log(this.data.flag)
      setTimeout(()=>{
        this.setData({
          flag: false
        })
      }, 2000)
    },
    "endIndex": function (nv,ov){
      if(!this.data.flag)this.init();
      this.setData({
        flag: true
      })
      setTimeout(()=>{
        this.setData({
          flag: false
        })
      }, 2000)
    },
    "progressActiveStyle": function(nv,ov){
      const newStylePosition = {
        left: `left: ${nv.left}px;`,
        right: `right: ${nv.right}px;`,
        tenLeft: `left: ${nv.left - 10}px;`,
        tenRight: `right: ${nv.right - 10}px;`,
        leftAddRight: `left: ${nv.left}px; right: ${nv.right}px;`
      }
      this.setData({
        stylePosition: newStylePosition
      })
    },
  },
  ready(){
    const query = wx.createSelectorQuery().in(this);
    query.select(".progress-bg").boundingClientRect((data) => {
        this.data.bodyWidth = data.width;
        this.init();
      })
      .exec();
  },
  methods:{
    computedHightClass(){
      const classList = [];
      for(let i = 0; i < this.data.points.length; i++){
        if(this.data.hightLightIndex.includes(i)){
          classList.push('hight-light');
        } else {
          classList.push('gray-light');
        }
      }
      this.setData({
        hightLightClass: classList
      })
    },
    setHightLight() {
      const { left, right } = this.data.progressActiveStyle;
      this.data.hightLightIndex = [
        Math.round(left / this.data.step),
        Math.round((this.data.bodyWidth - right) / this.data.step),
      ];
      if (!this.data.hightLightIndexBackUp.length) {
        this.data.hightLightIndexBackUp = this.data.hightLightIndex;
      }
      this.setData({
        hightLightIndex: this.data.hightLightIndex
      })
      this.computedHightClass();

    },
    setProgress({ left, right }) {
      if (left >= 0) {
        this.data.progressActiveStyle.left = left;
      }
      if (right >= 0) {
        if (this.data.bodyWidth - right >= 0) {
          this.data.progressActiveStyle.right = this.data.bodyWidth - right;
        }
      }
      this.setHightLight();
      this.setData({
        progressActiveStyle: this.data.progressActiveStyle
      })
    },
    checkMove(name, position) {
      const { left, right } = this.data.progressActiveStyle;
      const moveRight = position < this.data.bodyWidth - right;
      const moveLeft = position > left;
      if (this.data.bodyWidth - right - left <= this.data.step) {
        if (name === "rightBtnInfo" && moveRight) {
          return true;
        }
        if (name === "leftBtnInfo" && moveLeft) {
          return true;
        }
      }
      return false;
    },
    rightTouchstart(e) {
      this.triggerEvent("onTouch", "start");
      this.data.easyMove = false;
      this.data.rightBtnInfo.diff = e.touches[0].clientX - e.target.offsetLeft - 10;
    },
    rightTouchmove(e) {
      const position = e.touches[0].clientX - this.data.rightBtnInfo.diff;
      if (this.checkMove('rightBtnInfo', position)) {
        return;
      }
      this.setProgress({
        [this.getKeys('rightBtnInfo')]: position,
      });
    },
    rightTouchend(e) {
      this.triggerEvent("onTouch", "end");
      this.data.easyMove = true;
      const key = this.getKeys('rightBtnInfo');
      if (this.data.hightLightIndex[0] >= this.data.hightLightIndex[1]) {
        this.data.hightLightIndex = this.data.hightLightIndexBackUp;
      } else {
        this.data.hightLightIndexBackUp = this.data.hightLightIndex;
      }
      this.triggerEvent("onChange", {
        "right": this.data.points[this.data.hightLightIndex[1]],
        "left": this.data.points[this.data.hightLightIndex[0]],
      });
      this.setProgress({
        [key]: this.data.hightLightIndex[key === "left" ? 0 : 1] * this.data.step,
      });
    },
    leftTouchstart(e) {
      this.triggerEvent("onTouch", "start");
      this.data.easyMove = false;
      this.data.leftBtnInfo.diff = e.touches[0].clientX - e.target.offsetLeft - 10;
    },
    leftTouchmove(e) {
      const position = e.touches[0].clientX - this.data.leftBtnInfo.diff;
      if (this.checkMove('leftBtnInfo', position)) {
        return;
      }
      this.setProgress({
        [this.getKeys('leftBtnInfo')]: position,
      });
    },
    leftTouchend(e) {
      this.triggerEvent("onTouch", "end");
      this.data.easyMove = true;
      const key = this.getKeys('leftBtnInfo');
      if (this.data.hightLightIndex[0] >= this.data.hightLightIndex[1]) {
        this.data.hightLightIndex = this.data.hightLightIndexBackUp;
      } else {
        this.data.hightLightIndexBackUp = this.data.hightLightIndex;
      }
      this.triggerEvent("onChange", {
        "left": this.data.points[this.data.hightLightIndex[0]],
        "right": this.data.points[this.data.hightLightIndex[1]],

      });
      this.setProgress({
        [key]: this.data.hightLightIndex[key === "left" ? 0 : 1] * this.data.step,
      });
    },
    getKeys(name) {
      return {
        rightBtnInfo: "right",
        leftBtnInfo: "left",
      }[name];
    },
    init() {
      const step = this.data.bodyWidth / (this.data.points.length - 1);
      const endIndex = this.data.endIndex || this.data.points.length - 1;
      this.setData({
        step
      })
      this.setProgress({
        left: step * this.data.startIndex,
        right: step * endIndex,
      });
    },
  }
})
// dragRange.json
{
  "component": true
}
// dragRange.wxml
<view class="drag-range-container">
    <view class="progress-container">
      <view
        class="drag-btn-left drag-btn {{easyMove ? 'easy-btn' : ''}}"
        style="{{stylePosition.tenLeft}}"
        bindtouchmove="leftTouchmove"
        bindtouchstart="leftTouchstart"
        bindtouchend="leftTouchend"
        bindtouchcancel="leftTouchend"></view>
      <view
        class="drag-btn-right drag-btn {{easyMove ?'easy-btn' : ''}}"
        style="{{stylePosition.tenRight}}"
        bindtouchmove="rightTouchmove"
        bindtouchstart="rightTouchstart"
        bindtouchend="rightTouchend"
        bindtouchcancel="rightTouchend"></view>
      <view class="progress-bg"></view>
      <view
        class="progress-active {{easyMove ? 'easy-btn' : ''}}"
        style="{{stylePosition.leftAddRight}}"></view>
    </view>
    <view class="point-list">
      <view
        class="point-item {{hightLightClass[index]}}"
        wx:for="{{points}}"
        wx:key="*this">
        {{ item }}
      </view>
    </view>
  </view>
// dragRange.wxss
.easy-btn {
  transition: all 0.1s linear;
}
.drag-btn {
  width: 40rpx;
  height: 40rpx;
  border-radius: 50rpx;
  box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.2);
  background: #fff;
  z-index: 3;
  position: relative;
 
}
.drag-btn::before {
  content: "";
  display: block;
  position: absolute;
  width: 50rpx;
  height: 50rpx;
}
.point-item {
  color: #666666;
  font-size: 24rpx;
  width: 80rpx;
}
.point-list {
  margin-right: -25rpx;
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.progress-container {
  margin-left: 10rpx;
  margin-right: 10rpx;
  margin-bottom: 20rpx;
  height: 45rpx;
  position: relative;
}
.progress-bg {
  left: 0;
}
.progress-active {
  z-index: 2;
  background: #ff7600;
  border-radius: 50rpx;
  height: 10rpx;
}
.progress-bg {
  z-index: 1;
  width: 100%;
  height: 10rpx;
  border-radius: 50rpx;
  background: #f4f4f4;
}
.progress-bg,
.progress-active,
.drag-btn {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
}
.hight-light {
  color: #ff7600;
  font-weight: bold;
}

代码已经贴上去了,可以直接拿过去用
下面就是调用方式

// 在你需要调用这个滑动组件的文件中
// 1.先引入组件
···  // 这里我就不贴代码 了,每个人建的文件地址不一样,根据自己建的文件地址自己引入就可以了
// 2.调用组件
<view class="drag-container">  // 要给.drag-container一个宽度,我是加了一个边框。不然会溢出
  <dragRange  startIndex="{{getStartIndex}}" endIndex="{{getEndIndex}}"  points="{{kWPoints}}" bind:onTouch="onRangeChange" bind:onChange="onRangeChange"></dragRange>
</view>
//js中
data: {
    kWPoints: [
      "0",
      "20",
      "40",
      "80",
      "120",
      "160",
      "200",
      "360",
      "480",
      "720",
      "960",
    ],
    getStartIndex: 0,
    getEndIndex: 10,
    }
    onRangeChange(val){
	    console.log(val) //这个val就能拿到用户拖拽选择的值了,自己打印出来看看就知道了
	  },

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夕阳_醉了

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值