Blame view

uni_modules/uview-plus/components/u-slider/mpother.js 3.8 KB
a2702f6d   刘淇   巡查计划
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
  /**
   * 使用普通的js方案实现slider
   */
  export default {
      watch: {
          value(n) {
              // 只有在非滑动状态时,才可以通过value更新滑块值,这里监听,是为了让用户触发
              if (this.status === 'end') {
                  this.updateSliderPlacement(n, true)
              }
          }
      },
      mounted() {
          this.init()
      },
      methods: {
          init() {
              this.getSliderRect()
          },
          // 获取slider尺寸
          getSliderRect() {
              // 获取滑块条的尺寸信息
              setTimeout(() => {
                  this.$uGetRect('.u-slider').then((rect) => {
                      this.sliderRect = rect
                      this.updateSliderPlacement(this.value, true)
                  })
              }, 10)
          },
          // 是否可以操作
          canNotDo() {
              return this.disabled
          },
          // 获取当前手势点的X轴位移值
          getTouchX(e) {
              return e.touches[0].clientX
          },
          formatStep(value) {
              // 移动点占总长度的百分比
              return Math.round(Math.max(this.min, Math.min(value, this.max)) / this.step) * this.step
          },
          // 发出事件
          emitEvent(event, value) {
              this.$emit(event, value || this.value)
          },
          // 标记当前手势的状态
          setTouchStatus(status) {
              this.status = status
          },
          onTouchStart(e) {
              if (this.canNotDo()) {
                  return
              }
              // 标示当前的状态为开始触摸滑动
              this.emitEvent('start')
              this.setTouchStatus('start')
          },
          onTouchMove(e) {
              if (this.canNotDo()) {
                  return
              }
              // 滑块的左边不一定跟屏幕左边接壤,所以需要减去最外层父元素的左边值
              const x = this.getTouchX(e)
              const { left, width } = this.sliderRect
              const distanceX = x - left
              // 获得移动距离对整个滑块的百分比值,此为带有多位小数的值,不能用此更新视图
              // 否则造成通信阻塞,需要每改变一个step值时修改一次视图
              const percent = (distanceX / width) * 100
              this.setTouchStatus('moving')
              this.updateSliderPlacement(percent, true, 'moving')
          },
          onTouchEnd() {
              if (this.canNotDo()) {
                  return
              }
              this.emitEvent('end')
              this.setTouchStatus('end')
          },
          // 设置滑点的位置
          updateSliderPlacement(value, drag, event) {
              // 去掉小数部分,同时也是对step步进的处理
              const { width } = this.sliderRect
              const percent = this.formatStep(value)
              // 设置移动的值
              const barStyle = {
                  width: `${percent / 100 * width}px`
              }
              // 移动期间无需过渡动画
              if (drag === true) {
                  barStyle.transition = 'none'
              } else {
                  // 非移动期间,删掉对过渡为空的声明,让css中的声明起效
                  delete barStyle.transition
              }
              // 修改value值
              this.$emit('input', percent)
              // 事件的名称
              if (event) {
                  this.emitEvent(event, percent)
              }
              this.barStyle = barStyle
          },
          onClick(e) {
              if (this.canNotDo()) {
                  return
              }
              // 直接点击滑块的情况,计算方式与onTouchMove方法相同
              const { left, width } = this.sliderRect
              const value = ((e.detail.x - left) / width) * 100
              this.updateSliderPlacement(value, false, 'click')
          }
      }
  }