vue中双向滑块区间

1,428 阅读1分钟
<template>
  <div class="slider">
    <div class="title_num">{{startStep}}万一{{endStep}}万</div>
    <div class="ruler" id="ruler" ref="ruler">
      <div ref="bar" class="bar startbar" @touchstart="startTouchstart" @touchmove="startTouchmove">
        <div class="shuxian"></div>
        <div class="shuxian"></div>
        <div class="shuxian"></div>
      </div>
      <div ref="endbar" class="bar endbar" @touchstart="endTouchstart" @touchmove="endTouchmove">
        <div class="shuxian"></div>
        <div class="shuxian"></div>
        <div class="shuxian"></div>
      </div>
      <div ref="colorbar" class="barColor"></div>
    </div>
    <div class="date clearfix">
      <div class="fl">{{startStep}}</div>
      <div class="fr">{{endStep}}</div>
    </div>
  </div>
</template>
<script>
export default {
  data() {
    return {
      $ruler: "", // 滑竿
      $bar: "", // 左侧滑块
      $endbar: "", // 右侧滑块
      startX: "", // 左侧滑块位置
      endX: "", // 右侧滑块位置
      step: "", // 滑竿在限定范围内可以分多少步
      intervalStart: 0,
      intervalEnd: 500,
      startStep: 0,
      endStep: 500,
      amountW: "", //  滑竿多长距离
      endslidedis: 310, //右边滑块距离
      startslidedis: 0, //左边滑块距离
      endOff:0
    };
  },
  created() {
    const vm = this;
    vm.$nextTick(() => {
      vm.initSlider();
    });
  },
  methods: {
    initSlider() {
      const vm = this;
      vm.$ruler = vm.$refs.ruler;
      vm.$bar = vm.$refs.bar;
      vm.$endbar = vm.$refs.endbar;
      // 滑竿多长距离
      vm.amountW = vm.$ruler.clientWidth - vm.$bar.clientWidth;

      // 总共多少步
      vm.step = vm.amountW / (vm.intervalEnd - vm.intervalStart);
      this.valueReturn()
    },
    startTouchstart(e) {
      const vm = this;
      // 开始滑动时滑块的位置
      vm.startX = e.touches[0].pageX;

    },
    startTouchmove(e) {
      const vm = this;
      // 滑动距离=当前滑块x距离-最开始滑块距离
      let slidedis = e.touches[0].pageX - vm.$ruler.offsetLeft;
      if (slidedis >= 0) {
        this.startslidedis = slidedis;
      }

      //改变改变barcolor定位
      this.$refs.colorbar.style.left = this.startslidedis + "px";
      // 滑动距离小于0 或者大于滑竿的宽度,return掉
      if (slidedis < 0 || slidedis > vm.amountW) {
        ///避免滑动到最左边是不灵敏现象
         this.startStep=0
          vm.$bar.style.left = "0px";
          this.barColorFn()
        return;
      }

      let ste = Math.round(slidedis / vm.step);
      if (ste + vm.intervalStart >= vm.endStep) {
        return;
      }
      vm.startStep = ste + vm.intervalStart;
      //改变barcolor宽度
      this.barColorFn();
      vm.$endbar.style.zIndex=2
       vm.$bar.style.zIndex=10
      vm.$bar.style.left = ste * vm.step + "px";
      this.valueReturn()
    },
    endTouchstart(e) {
      const vm = this;
      // 开始滑动时滑块的位置
      vm.endX = e.touches[0].pageX;
    },
    endTouchmove(e) {
      const vm = this;
      // 滑动距离=当前滑块x距离-最开始滑块距离
      let slidedis = e.touches[0].pageX - vm.$ruler.offsetLeft;
      if (slidedis <= this.endOff) {
        this.endslidedis = slidedis;
      }
      if (slidedis < 0 || slidedis > vm.amountW) {
        // if(this.endStep>=495){
          ///避免滑动到最右边是不灵敏现象
          this.endStep=500
          vm.$endbar.style.left = "";
          vm.$endbar.style.right = "0px";
          this.barColorFn()
        // }
        return;
      }
      let ste = Math.round(slidedis / vm.step);

      if (vm.startStep >= ste + vm.intervalStart) {
        console.log(999)
        return;
      }
      vm.endStep = ste + vm.intervalStart;

      if (vm.endStep == 24) {
        vm.$endbar.style.left = "";
        vm.$endbar.style.right = "0px";
      } else {
        vm.$endbar.style.left = ste * vm.step + "px";
      }
       vm.$endbar.style.zIndex=10
       vm.$bar.style.zIndex=2
      //改变barcolor宽度
      this.barColorFn();
      this.valueReturn()
    },
    //计算barColor宽度
    barColorFn() {
      let widths = this.endslidedis - this.startslidedis;
       if(widths<24){
         this.$refs.colorbar.style.width = 0 + "px";
      return;
       }
      // // if(widths<=331){
      this.$refs.colorbar.style.width = widths + "px";

      // }
    },
    //返回确认值
    valueReturn(){
       let val=this.startStep+'-'+this.endStep
      if(this.endStep==500){
          val=this.startStep+'-'
      }
       this.$emit('slierFn',val)
    },
    //初始化滑块宽度
    initBar(){

    },

  },
  mounted(){
        this.endslidedis=this.$refs.colorbar.clientWidth
        this.endOff=this.$refs.colorbar.clientWidth
  }
};
</script>
<style lang="scss" scoped>
.clearfix {
  &:after {
    content: "";
    display: block;
    clear: both;
  }
}
.slider {
  margin: auto;
  width: 562px;
  //   overflow: hidden;
  .date {
    color: #333;
    font-size: 0.7rem;
    margin-top: 8px;
    font-size: 28px;
    font-family: Source Han Sans CN;
    font-weight: 400;
    color: rgba(153, 153, 153, 1);
    .fl {
      float: left;
    }
    .fr {
      float: right;
    }
  }
  .ruler {
    height: 11px;
    position: relative;
    margin-top: 35px;
    background: rgba(249, 249, 249, 1);
    border-radius: 30px;
    width: 100%;
    .bar {
      position: absolute;
      border-radius: 100%;
      text-align: center;
      width: 44px;
      height: 44px;
      background: rgba(255, 255, 255, 1);
      box-shadow: 0px 0px 13px 0px rgba(133, 57, 42, 0.2);
      border-radius: 50%;
      top: -17.5px;
      z-index: 10;
      display: flex;
      justify-content: space-between;
      align-items: center;
      box-sizing: border-box;
      padding: 10px;
      .shuxian {
        width: 2px !important;
        height: 16px;
        background: rgba(255, 106, 76, 1);
        border-radius: 1px;
        z-index: 11;
      }
    }
    .startbar {
      left: 0;
    }
    .endbar {
      right: 0;
    }
    .barColor {
      position: absolute;
      width: 100%;
      display: inline-block;
      height: 11px;
      background: rgba(255, 106, 76, 1);
    }
  }
  .title_num {
    text-align: center;
    font-size: 32px;
    font-family: Source Han Sans CN;
    font-weight: 400;
    color: rgba(51, 51, 51, 1);
  }
}
</style>