Blame view

node_modules/uview-ui/components/u-slider/mpother.js 3.91 KB
c7add6cf   “wangming”   初始版本开发完毕
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')

          }

      }

  }