touchEvent.js
3.58 KB
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
/* 此插件的设计仅是因为vue-touch官方还不支持vue 2.0 所做的过渡方案 */
/*
* 使用方法:
* 1. 注册插件
* - import VueTouch from './plugins/touchEvent'
* - Vue.use(VueTouch)
* 2. 侦听事件
* - <span v-touch:hold="func"></span>
* - 触摸方法: hold(长按) tap(短按) swiperight(右划) swipeleft(左划) swipetop swipedown
* - 绑定参数: dom节点的data-set属性
*/
import Vue from 'vue'
const TouchEventPlugin = Object.create(null)
TouchEventPlugin.install = function (Vue) {
// 添加全局资源
Vue.directive('touch', {
//传入的模式 hold swiperight swipeleft swipetop swipedown tap
bind: function (el, binding, vnode) {
// Vue 编译生成的虚拟节点
// vnode = (vnode && vnode.data && vnode.data.attrs) || {}
vnode = vnode || {}
// 传给指令的参数。例如 v-touch:swipeRight, arg 的值是 "swipeRight"
let touchType = binding.arg.toLowerCase()
var timeOutEvent = 0
var direction = ''
//滑动处理
var startX = null
var startY = null
//返回角度
function GetSlideAngle(dx, dy) {
return Math.atan2(dy, dx) * 180 / Math.PI
}
//根据起点和终点返回方向 1:向上,2:向下,3:向左,4:向右,0:未滑动
function GetSlideDirection (startX, startY, endX, endY) {
let dy = startY - endY
let dx = endX - startX
let result = 0
//如果滑动距离太短
if (Math.abs(dx) < 2 && Math.abs(dy) < 2) {
return result
}
let angle = GetSlideAngle(dx, dy)
if (angle >= -45 && angle < 45) {
result = 'swiperight'
} else if (angle >= 45 && angle < 135) {
result = 'swipeup'
} else if (angle >= -135 && angle < -45) {
result = 'swipedown'
} else if ((angle >= 135 && angle <= 180) || (angle >= -180 && angle < -135)) {
result = 'swipeleft'
}
return result
}
el.addEventListener('touchstart', function (ev) {
startX = ev.touches[0].pageX
startY = ev.touches[0].pageY
//判断长按
timeOutEvent = setTimeout(() => {
timeOutEvent = 0
if (touchType === 'hold'){
binding.value(vnode)
}
} , 800)
}, false)
el.addEventListener('touchmove' , function (ev) {
if (timeOutEvent) {
clearTimeout(timeOutEvent)
timeOutEvent = 0
}
})
el.addEventListener('touchend', function (ev) {
if (timeOutEvent) {
clearTimeout(timeOutEvent)
timeOutEvent = 0
}
let endX = ev.changedTouches[0].pageX
let endY = ev.changedTouches[0].pageY
direction = GetSlideDirection(startX, startY, endX, endY)
switch (direction) {
case 0:
if (touchType === 'tap'){
binding.value(vnode)
}
break
case 'swipeup':
if (touchType === 'swipeup'){
binding.value(vnode)
}
break
case 'swipedown':
if (touchType === 'swipedown'){
binding.value(vnode)
}
break
case 'swipeleft':
if (touchType === 'swipeleft'){
binding.value(vnode)
}
break
case 'swiperight':
if (touchType === 'swiperight'){
binding.value(vnode)
}
break
default:
break
}
}, false)
}
})
}
export default TouchEventPlugin