-
Notifications
You must be signed in to change notification settings - Fork 27
/
jquery.longclick.js
146 lines (132 loc) · 4.52 KB
/
jquery.longclick.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
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
136
137
138
139
140
141
142
143
144
145
146
/**
* jQuery Longclick Event
* ======================
* Press & hold mouse button "long click" special event for jQuery 1.4.x
*
* @license Longclick Event
* Copyright (c) 2010 Petr Vostrel (http://petr.vostrel.cz/)
* Dual licensed under the MIT (MIT-LICENSE.txt)
* and GPL (GPL-LICENSE.txt) licenses.
*
* Version: 0.3.2
* Updated: 2010-06-22
*/
(function($){
/*
`.click( duration, handler )`
* Simply supply `duration` to the well-known `.click` method and you have a *long click*.
* This method is a shortcut for `.bind("longclick", handler)`.
* Returns *jQuery*.
*/
var
$_fn_click= $.fn.click
$.fn.click= function click(duration, handler){
/* Shortcircuit ordinary click calls */
if (!handler) return $_fn_click.apply(this, arguments)
/* Bind long click */
return $(this).data(_duration_, duration || null).bind(type, handler)
}
/*
`.longclick( [ duration ], [ handler ] )`
* If supplied, optional custom `duration` is used for target element(s).
* This method is a shortcut for `.click(duration, handler)` when at least `handler` is supplied
and for `.trigger("longclick")` if called without arguments.
* Returns *jQuery*.
*/
$.fn.longclick= function longclick(){
var
args= [].splice.call(arguments, 0),
handler= args.pop(),
duration= args.pop(),
$this= $(this).data(_duration_, duration || null)
return handler ? $this.click(duration, handler) : $this.trigger(type)
}
/*
Configuration
*/
$.longclick= {
/*
* For how long (in milliseconds) mouse button must be pressed down (or touched) stationery
to qualify as a *long click*.
* False value results in using the configured default.
* Default `duration` is **500** and is stored in `jQuery.longclick.duration` variable.
*/
duration: 500
}
/*
Bindings
*/
$.event.special.longclick= {
setup: function(data, namespaces){
if (!(/iphone|ipad|ipod/i).test(navigator.userAgent)){
/* normal technique for standard mouse-based interaction */
$(this)
.bind(_mousedown_, schedule)
.bind([_mousemove_, _mouseup_, _mouseout_, _contextmenu_].join(' '), annul)
.bind(_click_, click)
}else{
/* and special handling for touch-based interaction on iPhone-compatibile devices */
touch_enabled(this)
.bind(_touchstart_, schedule)
.bind([_touchend_, _touchmove_, _touchcancel_].join(' '), annul)
.bind(_click_, click)
.css({ WebkitUserSelect: 'none' })
}
},
teardown: function(namespaces){
$(this).unbind(namespace)
}
}
/*
Commit subset of touch events to trigger jQuery events of same names
*/
function touch_enabled(element){
$.each('touchstart touchmove touchend touchcancel'.split(/ /), function bind(ix, it){
element.addEventListener(it, function trigger_jquery_event(event){ $(element).trigger(it) }, false);
});
return $(element);
}
/*
Handlers
*/
function schedule(event){
/* Check the timer isn't already running and drop if so */
if ($(this).data(_timer_)) return;
/* Catch in closure the `this` reference and `arguments` for later */
var
element= this,
args= arguments
/* Flag as "not fired" and schedule the trigger */
$(this)
.data(_fired_, false)
.data(_timer_, setTimeout(scheduled, $(this).data(_duration_) || $.longclick.duration))
function scheduled(){
/* Flag as "fired" and rejoin the default event flow */
$(element).data(_fired_, true)
event.type= type
jQuery.event.handle.apply(element, args)
}
}
function annul(event){
/* Annul the scheduled trigger */
$(this).data(_timer_, clearTimeout($(this).data(_timer_)) || null)
}
function click(event){
/* Prevent `click` event to be fired after button release once `longclick` was fired */
if ($(this).data(_fired_)) return event.stopImmediatePropagation() || false
}
/*
Frequent primitives and shortcuts
*/
var
type= 'longclick',
namespace= '.' + type,
/* Event strings */
_mousedown_= 'mousedown'+namespace, _click_= 'click'+namespace,
_mousemove_= 'mousemove'+namespace, _mouseup_= 'mouseup'+namespace,
_mouseout_= 'mouseout'+namespace, _contextmenu_= 'contextmenu'+namespace,
_touchstart_= 'touchstart'+namespace, _touchend_= 'touchend'+namespace,
_touchmove_= 'touchmove'+namespace, _touchcancel_= 'touchcancel'+namespace,
/* Storage keys */
_duration_= 'duration'+namespace, _timer_= 'timer'+namespace, _fired_= 'fired'+namespace
})(jQuery);