148 lines
No EOL
4.4 KiB
JavaScript
148 lines
No EOL
4.4 KiB
JavaScript
/**
|
|
* 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: 600
|
|
}
|
|
|
|
/*
|
|
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)
|
|
//jQuery.event.dispatch.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); |