UNPKG

11.1 kBJavaScriptView Raw
1// EventUtil 事件函数
2var EventUtil = function () {
3 /**
4 * 多次点击事件
5 * @param {DOM} element 目标元素
6 * @param {String} type 事件名称, 此处固定为'countclick'
7 * @param {Function} handler 句柄, handler({code(1成功0失败): '1'或'0', count(点击次数): Number, ...e})
8 * @param {Boolean} isDetach 是否移除绑定事件
9 * @param {Object} params 定义配置, 配置为: {count(点击次数): Number, timeout(超时时长): Number}
10 */
11 var _countClickEventHandler = function _countClickEventHandler(e) {
12 // 解析参数
13 var target = e.currentTarget;
14 // 次数自增
15 target.prevCount += 1;
16 e.count = target.prevCount;
17 e.code = '0';
18
19 // 当第一次点击时记录时间
20 if (target.prevCount === 1) {
21 target.prevTime = new Date().getTime();
22 }
23
24 // 当次数满足条件时
25 if (target.prevCount >= target.count) {
26 // 如果时间也满足条件, 则通过
27 if (new Date().getTime() - target.prevTime <= target.timeout) {
28 e.code = '1';
29 }
30 target.prevCount = 0;
31 }
32
33 target.handler(e);
34 };
35 var _countClickEvent = function _countClickEvent(element, type, handler, isDetach, params) {
36 // 构建参数
37 element.prevCount = 0;
38 element.prevTime = new Date().getTime();
39 element.count = params && params.count ? params.count : 10; // 点击多少次触发
40 element.timeout = params && params.timeout ? params.timeout : 5000; // 点击间隔秒数
41 element.handler = handler;
42 // 添加或移除事件
43 function attach() {
44 element.addEventListener('click', _countClickEventHandler, false);
45 }
46 function detach() {
47 element.removeEventListener('click', _countClickEventHandler, false);
48 }
49 if (isDetach) {
50 detach();
51 } else {
52 attach();
53 }
54 };
55 /**
56 * 触摸事件
57 * @param {DOM} element 目标元素
58 * @param {String} type 事件名称, 此函数处理tap | swipeleft | swiperight | swipedown | swipeup事件
59 * @param {Function} handler 句柄, handler(e)
60 * @param {Boolean} isDetach 是否移除绑定事件, 此为一函数对多type, 所以不允许移除事件, 只能移除句柄
61 */
62 var _touchEvent = function _touchEvent(element, type, handler, isDetach) {
63 var params = {
64 threshold: 0
65 /* ------------------------
66 Model
67 ------------------------ */
68 };var touches = {
69 direction: 0,
70 vertical: 0,
71 horizontal: 0,
72 startX: 0,
73 startY: 0,
74 endX: 0,
75 endY: 0,
76 diffX: 0,
77 diffY: 0
78 /* ------------------------
79 Touch Handler
80 ------------------------ */
81 };var onTouchStart = function onTouchStart(e) {
82 touches.startX = e.touches[0].clientX;
83 touches.startY = e.touches[0].clientY;
84 };
85 var onTouchEnd = function onTouchEnd(e) {
86 var eventName = '';
87 touches.endX = e.changedTouches[0].clientX;
88 touches.endY = e.changedTouches[0].clientY;
89 touches.diffX = touches.startX - touches.endX;
90 touches.diffY = touches.startY - touches.endY;
91 // 单击事件
92 if (Math.abs(touches.diffX) < 6 && Math.abs(touches.diffY) < 6) {
93 eventName = 'tap';
94 }
95
96 // 设置方向
97 if (touches.direction === 0) {
98 // 设置滑动方向(-1上下 | 1左右)
99 touches.direction = Math.abs(touches.diffX) > Math.abs(touches.diffY) ? 1 : -1;
100 }
101 if (touches.direction === -1) {
102 // 设置垂直方向(-1上 | 1下)
103 touches.vertical = touches.diffY < 0 ? 1 : -1;
104 }
105 if (touches.direction === 1) {
106 // 设置左右方向(-1左 | 1右)
107 touches.horizontal = touches.diffX < 0 ? 1 : -1;
108 }
109
110 // swipeleft | swiperight | swipedown | swipeup 事件
111 if (touches.vertical === -1) {
112 // 上
113 if (Math.abs(touches.diffY) > params.threshold) {
114 eventName = 'swipeup';
115 }
116 } else if (touches.vertical === 1) {
117 // 下
118 if (Math.abs(touches.diffY) > params.threshold) {
119 eventName = 'swipedown';
120 }
121 } else if (touches.horizontal === -1) {
122 // 左
123 if (Math.abs(touches.diffY) > params.threshold) {
124 eventName = 'swipeleft';
125 }
126 } else if (touches.horizontal === 1) {
127 // 右
128 if (Math.abs(touches.diffY) > params.threshold) {
129 eventName = 'swiperight';
130 }
131 }
132 // 清空方向
133 touches.direction = 0;
134 touches.vertical = 0;
135 touches.horizontal = 0;
136 // 执行函数
137 for (var n in element.touchEvents) {
138 if (eventName === n) element.touchEvents[n](e);
139 }
140 };
141 /* ------------------------
142 Touch Events
143 ------------------------ */
144 // 绑定事件
145 var attach = function attach() {
146 if (Object.keys(element.touchEvents || {}).length === 0) {
147 element.touchEvents = {};
148 element['addEventListener']('touchstart', onTouchStart, false);
149 element['addEventListener']('touchend', onTouchEnd, false);
150 }
151 element.touchEvents[type] = handler;
152 };
153 // 移除事件
154 var detach = function detach() {
155 if (element.touchEvents) delete element.touchEvents[type];
156 if (Object.keys(element.touchEvents || {}).length === 0) {
157 element['removeEventListener']('touchstart', onTouchStart, false);
158 element['removeEventListener']('touchend', onTouchEnd, false);
159 }
160 };
161 // 添加或移除事件
162 if (isDetach) {
163 detach();
164 } else {
165 attach();
166 }
167 };
168 /**
169 * 摇动事件
170 * @param {DOM} element 无
171 * @param {String} type 事件名称, 此函数处理shake事件
172 * @param {Function} handler 句柄, handler(e)
173 * @param {Boolean} isDetach 是否移除绑定事件
174 */
175 var _shake_handler = null;
176 var _shake_threshold = 3000; // 晃动速度
177 var _shake_lastUpdate = 0; // 设置最后更新时间, 用于对比
178 var _shake_curShakeX = 0;
179 var _shake_curShakeY = 0;
180 var _shake_curShakeZ = 0;
181 var _shake_lastShakeX = 0;
182 var _shake_lastShakeY = 0;
183 var _shake_lastShakeZ = 0;
184 var _shakeEventHandler = function _shakeEventHandler(e) {
185 var acceleration = e.accelerationIncludingGravity; // 获得重力加速
186 var curTime = new Date().getTime(); // 获得当前时间戳
187 if (curTime - _shake_lastUpdate > 100) {
188 var diffTime = curTime - _shake_lastUpdate; // 时间差
189 _shake_lastUpdate = curTime;
190 _shake_curShakeX = acceleration.x; // x轴加速度
191 _shake_curShakeY = acceleration.y; // y轴加速度
192 _shake_curShakeZ = acceleration.z; // z轴加速度
193 var speed = Math.abs(_shake_curShakeX + _shake_curShakeY + _shake_curShakeZ - _shake_lastShakeX - _shake_lastShakeY - _shake_lastShakeZ) / diffTime * 10000;
194 if (speed > _shake_threshold) {
195 e.speed = speed;
196 if (_shake_handler) _shake_handler(e);
197 }
198 _shake_lastShakeX = _shake_curShakeX;
199 _shake_lastShakeY = _shake_curShakeY;
200 _shake_lastShakeZ = _shake_curShakeZ;
201 }
202 };
203 var _shakeEvent = function _shakeEvent(element, type, handler, isDetach) {
204 _shake_handler = handler;
205 function attach() {
206 window.addEventListener('devicemotion', _shakeEventHandler, false);
207 }
208 function detach() {
209 window.removeEventListener('devicemotion', _shakeEventHandler, false);
210 }
211 // 添加或移除事件
212 if (isDetach) {
213 detach();
214 } else {
215 attach();
216 }
217 };
218 /**
219 * 返回
220 */
221 return {
222 addHandler: function addHandler(element, type, handler, params) {
223 // params用于多次点击时控制次数与时长
224 // 自定义事件 countclick
225 if (type === 'countclick') {
226 _countClickEvent(element, 'countclick', handler, false, params); // params: {count: 10, timeout: 5000}
227 return;
228 }
229 // touch兼容PC事件
230 var isSupportTouch = 'ontouchstart' in window;
231 if (!isSupportTouch) {
232 if (type === 'touchstart') type = 'mousedown';
233 if (type === 'touchmove') type = 'mousemove';
234 if (type === 'touchend') type = 'mouseup';
235 if (type === 'touchcancel') type = 'mouseup';
236 if (type === 'tap') type = 'click';
237 } else {
238 // 自定义事件 tap | swipeleft | swiperight | swipedown | swipeup
239 if (type === 'tap' || type === 'swipeleft' || type === 'swiperight' || type === 'swipedown' || type === 'swipeup') {
240 _touchEvent(element, type, handler);
241 return;
242 }
243 }
244 // 重力感应事件
245 if (type === 'shake') {
246 if (window.DeviceMotionEvent) {
247 _shakeEvent(element, 'shake', handler);
248 } else {
249 console.warn('此设备不支持重力感应');
250 }
251 return;
252 }
253 // 系统事件
254 if (element.addEventListener) {
255 element.addEventListener(type, handler, false);
256 } else if (element.attachEvent) {
257 element.attachEvent('on' + type, handler);
258 } else {
259 element['on' + type] = handler;
260 }
261 },
262 removeHandler: function removeHandler(element, type, handler) {
263 // 自定义事件 countclick
264 if (type === 'countclick') {
265 _countClickEvent(element, 'countclick', null, true);
266 return;
267 }
268 // touch兼容PC事件
269 var isSupportTouch = 'ontouchstart' in window;
270 if (!isSupportTouch) {
271 if (type === 'touchstart') type = 'mousedown';
272 if (type === 'touchmove') type = 'mousemove';
273 if (type === 'touchend') type = 'mouseup';
274 if (type === 'touchcancel') type = 'mouseup';
275 if (type === 'tap') type = 'click';
276 } else {
277 // 自定义事件 tap | swipeleft | swiperight | swipedown | swipeup
278 if (type === 'tap' || type === 'swipeleft' || type === 'swiperight' || type === 'swipedown' || type === 'swipeup') {
279 _touchEvent(element, type, handler, true);
280 return;
281 }
282 }
283 // 重力感应事件
284 if (type === 'shake') {
285 if (window.DeviceMotionEvent) {
286 _shakeEvent(element, 'shake', handler, true);
287 } else {
288 console.warn('此设备不支持重力感应');
289 }
290 return;
291 }
292 // 系统事件
293 if (element.removeEventListener) {
294 element.removeEventListener(type, handler, false);
295 } else if (element.detachEvent) {
296 element.detachEvent('on' + type, handler);
297 } else {
298 element['on' + type] = null;
299 }
300 },
301 preventDefault: function preventDefault(e) {
302 if (e.preventDefault) {
303 e.preventDefault();
304 } else {
305 e.returnValue = false;
306 }
307 },
308 stopPropagation: function stopPropagation(e) {
309 if (e.stopPropagation) {
310 e.stopPropagation();
311 } else {
312 e.cancelBubble = true;
313 }
314 },
315 event: function event(e) {
316 return e || window.e;
317 },
318 type: function type(e) {
319 return e.type;
320 },
321 target: function target(e) {
322 return e.target || e.srcElement;
323 }
324 };
325}();
326
327export default EventUtil;
\No newline at end of file