zjf
2023-03-03 bafa9dff4d9880c562f4d3a7b83bd4c1129240c5
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
 
// 盒子滚动条拖拽
import { on, off } from '@/utils/dom'
import Vue from 'vue'
import { debounce } from 'throttle-debounce'
 
let targetDrag = { // 托拽
  isDown: false,
  coord: {
    x: 0,
    y: 0
  }
}
 
let dom = null
let ignoreClass = [] // 忽略的类名
 
const scrollMousedown = event => {
  dom.style.cursor = 'pointer'
  targetDrag.isDown = true
  targetDrag.coord.x = event.pageX
  targetDrag.coord.y = event.pageY
}
 
const scrollMouseup = event => {
  dom.style.cursor = 'default'
  targetDrag.isDown = false
  targetDrag.coord.x = 0
  targetDrag.coord.y = 0
}
 
const scrollMousemove = event => {
  const movX = targetDrag.coord.x - event.pageX
  targetDrag.coord.x = event.pageX
  if (checkDomIsIgnore(event)) {
    dom.style.cursor = 'default'
    targetDrag.isDown = false
  } else if (targetDrag.isDown) {
    dom.scrollLeft = dom.scrollLeft + movX
  }
}
 
const scrollMouseout = event => {
  dom.style.cursor = 'default'
  targetDrag.isDown = false
}
 
const scrollMousewheel = event => {
  if (checkIsIgnore(event)) {
    dom.style.cursor = 'default'
    targetDrag.isDown = false
  } else {
    dom.scrollLeft += event.deltaY
  }
}
 
/**
 * 检查dom是否忽略
 * @param {*} e
 */
const checkDomIsIgnore = debounce(300, (e) => {
  let ignore = false
  ignoreClass.forEach(element => {
    var items = document.getElementsByClassName(element)
    if (items && !ignore) {
      for (let index = 0; index < items.length; index++) {
        const element = items[index]
        if (element.contains(e.target)) {
          ignore = true
          break
        }
      }
    }
  })
  return ignore
})
 
/**
 * 忽略滚轮
 * @param {*} e
 */
const checkIsIgnore = (e) => {
  let ignore = false
  ignoreClass.forEach(element => {
    var items = document.getElementsByClassName(element)
    if (items && !ignore) {
      for (let index = 0; index < items.length; index++) {
        const element = items[index]
        const rect = element.getBoundingClientRect()
        if ((e.clientY > rect.top && (e.clientY < (rect.top + rect.height))) && (e.clientX > rect.left && (e.clientX < (rect.left + rect.width)))) {
          ignore = true
          break
        }
      }
    }
  })
  return ignore
}
 
export default Vue.directive('scrollx', {
  bind: function (el, binding, vnode) {
    const valueData = binding.value
    ignoreClass = valueData.ignoreClass
  },
 
  inserted: function (el) {
    dom = el
 
    // 鼠标按下
    on(el, 'mousedown', scrollMousedown)
    on(el, 'mouseout', scrollMouseout)
    on(el, 'wheel', scrollMousewheel)
    // 鼠标释放
    on(el, 'mouseup', scrollMouseup)
    // 鼠标托拽
    on(el, 'mousemove', scrollMousemove)
  },
 
  unbind: function (el) {
    off(el, 'mousedown', scrollMousedown)
    off(el, 'mouseup', scrollMouseup)
    off(el, 'mouseout', scrollMouseout)
    off(el, 'wheel', scrollMousewheel)
    off(el, 'mousemove', scrollMousemove)
 
    // 清空
    targetDrag = { // 托拽
      isDown: false,
      coord: {
        x: 0,
        y: 0
      }
    }
  }
})