-
Notifications
You must be signed in to change notification settings - Fork 19
/
jquery.tap.js
96 lines (86 loc) · 3 KB
/
jquery.tap.js
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
(function($, specialEventName, marginX, marginY) {
'use strict';
/**
* Native event names for creating custom one.
*
* @type {Object}
*/
var nativeEvent = Object.create(null);
/**
* Get current time.
*
* @return {Number}
*/
var getTime = function() {
return new Date().getTime();
};
nativeEvent.original = 'click';
if ('ontouchstart' in document) {
nativeEvent.start = 'touchstart';
nativeEvent.end = 'touchend';
} else {
nativeEvent.start = 'mousedown';
nativeEvent.end = 'mouseup';
}
$.event.special[specialEventName] = {
setup: function(data, namespaces, eventHandle) {
var $element = $(this);
var eventData = {};
$element
// Remove all handlers that were set for an original event.
.off(nativeEvent.original)
// Prevent default actions.
.on(nativeEvent.original, false)
// Split original event by two different and collect an information
// on every phase.
.on(nativeEvent.start + ' ' + nativeEvent.end, function(event) {
// Handle the event system of touchscreen devices.
eventData.event = event.originalEvent.changedTouches ? event.originalEvent.changedTouches[0] : event;
})
.on(nativeEvent.start, function(event) {
// Stop execution if an event is simulated.
if (event.which && event.which !== 1) {
return;
}
eventData.target = event.target;
eventData.pageX = eventData.event.pageX;
eventData.pageY = eventData.event.pageY;
eventData.time = getTime();
})
.on(nativeEvent.end, function(event) {
// Compare properties from two phases.
if (
// The target should be the same.
eventData.target === event.target &&
// Time between first and last phases should be less than 750 ms.
getTime() - eventData.time < 750 &&
// Coordinates, when event ends, should be almost the same as
// they were on start.
(
Math.abs(eventData.pageX - eventData.event.pageX) <= marginX &&
Math.abs(eventData.pageY - eventData.event.pageY) <= marginY
)
) {
event.type = specialEventName;
event.pageX = eventData.event.pageX;
event.pageY = eventData.event.pageY;
eventHandle.call(this, event);
// If an event wasn't prevented then execute original actions.
if (!event.isDefaultPrevented()) {
$element
// Remove prevention of default actions.
.off(nativeEvent.original)
// Bring the action.
.trigger(nativeEvent.original);
}
}
});
},
remove: function() {
$(this).off(nativeEvent.start + ' ' + nativeEvent.end);
}
};
$.fn[specialEventName] = function(fn) {
return this[fn ? 'on' : 'trigger'](specialEventName, fn);
};
})(jQuery, 'tap', 10, 10);