301 lines
8.0 KiB
JavaScript
301 lines
8.0 KiB
JavaScript
(function() {
|
|
|
|
var event = jQuery.event,
|
|
|
|
//helper that finds handlers by type and calls back a function, this is basically handle
|
|
// events - the events object
|
|
// types - an array of event types to look for
|
|
// callback(type, handlerFunc, selector) - a callback
|
|
// selector - an optional selector to filter with, if there, matches by selector
|
|
// if null, matches anything, otherwise, matches with no selector
|
|
findHelper = function( events, types, callback, selector ) {
|
|
var t, type, typeHandlers, all, h, handle,
|
|
namespaces, namespace,
|
|
match;
|
|
for ( t = 0; t < types.length; t++ ) {
|
|
type = types[t];
|
|
all = type.indexOf(".") < 0;
|
|
if (!all ) {
|
|
namespaces = type.split(".");
|
|
type = namespaces.shift();
|
|
namespace = new RegExp("(^|\\.)" + namespaces.slice(0).sort().join("\\.(?:.*\\.)?") + "(\\.|$)");
|
|
}
|
|
typeHandlers = (events[type] || []).slice(0);
|
|
|
|
for ( h = 0; h < typeHandlers.length; h++ ) {
|
|
handle = typeHandlers[h];
|
|
|
|
match = (all || namespace.test(handle.namespace));
|
|
|
|
if(match){
|
|
if(selector){
|
|
if (handle.selector === selector ) {
|
|
callback(type, handle.origHandler || handle.handler);
|
|
}
|
|
} else if (selector === null){
|
|
callback(type, handle.origHandler || handle.handler, handle.selector);
|
|
}
|
|
else if (!handle.selector ) {
|
|
callback(type, handle.origHandler || handle.handler);
|
|
|
|
}
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Finds event handlers of a given type on an element.
|
|
* @param {HTMLElement} el
|
|
* @param {Array} types an array of event names
|
|
* @param {String} [selector] optional selector
|
|
* @return {Array} an array of event handlers
|
|
*/
|
|
event.find = function( el, types, selector ) {
|
|
var events = ( $._data(el) || {} ).events,
|
|
handlers = [],
|
|
t, liver, live;
|
|
|
|
if (!events ) {
|
|
return handlers;
|
|
}
|
|
findHelper(events, types, function( type, handler ) {
|
|
handlers.push(handler);
|
|
}, selector);
|
|
return handlers;
|
|
};
|
|
/**
|
|
* Finds all events. Group by selector.
|
|
* @param {HTMLElement} el the element
|
|
* @param {Array} types event types
|
|
*/
|
|
event.findBySelector = function( el, types ) {
|
|
var events = $._data(el).events,
|
|
selectors = {},
|
|
//adds a handler for a given selector and event
|
|
add = function( selector, event, handler ) {
|
|
var select = selectors[selector] || (selectors[selector] = {}),
|
|
events = select[event] || (select[event] = []);
|
|
events.push(handler);
|
|
};
|
|
|
|
if (!events ) {
|
|
return selectors;
|
|
}
|
|
//first check live:
|
|
/*$.each(events.live || [], function( i, live ) {
|
|
if ( $.inArray(live.origType, types) !== -1 ) {
|
|
add(live.selector, live.origType, live.origHandler || live.handler);
|
|
}
|
|
});*/
|
|
//then check straight binds
|
|
findHelper(events, types, function( type, handler, selector ) {
|
|
add(selector || "", type, handler);
|
|
}, null);
|
|
|
|
return selectors;
|
|
};
|
|
event.supportTouch = "ontouchend" in document;
|
|
|
|
$.fn.respondsTo = function( events ) {
|
|
if (!this.length ) {
|
|
return false;
|
|
} else {
|
|
//add default ?
|
|
return event.find(this[0], $.isArray(events) ? events : [events]).length > 0;
|
|
}
|
|
};
|
|
$.fn.triggerHandled = function( event, data ) {
|
|
event = (typeof event == "string" ? $.Event(event) : event);
|
|
this.trigger(event, data);
|
|
return event.handled;
|
|
};
|
|
/**
|
|
* Only attaches one event handler for all types ...
|
|
* @param {Array} types llist of types that will delegate here
|
|
* @param {Object} startingEvent the first event to start listening to
|
|
* @param {Object} onFirst a function to call
|
|
*/
|
|
event.setupHelper = function( types, startingEvent, onFirst ) {
|
|
if (!onFirst ) {
|
|
onFirst = startingEvent;
|
|
startingEvent = null;
|
|
}
|
|
var add = function( handleObj ) {
|
|
|
|
var bySelector, selector = handleObj.selector || "";
|
|
if ( selector ) {
|
|
bySelector = event.find(this, types, selector);
|
|
if (!bySelector.length ) {
|
|
$(this).delegate(selector, startingEvent, onFirst);
|
|
}
|
|
}
|
|
else {
|
|
//var bySelector = event.find(this, types, selector);
|
|
if (!event.find(this, types, selector).length ) {
|
|
event.add(this, startingEvent, onFirst, {
|
|
selector: selector,
|
|
delegate: this
|
|
});
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
remove = function( handleObj ) {
|
|
var bySelector, selector = handleObj.selector || "";
|
|
if ( selector ) {
|
|
bySelector = event.find(this, types, selector);
|
|
if (!bySelector.length ) {
|
|
$(this).undelegate(selector, startingEvent, onFirst);
|
|
}
|
|
}
|
|
else {
|
|
if (!event.find(this, types, selector).length ) {
|
|
event.remove(this, startingEvent, onFirst, {
|
|
selector: selector,
|
|
delegate: this
|
|
});
|
|
}
|
|
}
|
|
};
|
|
$.each(types, function() {
|
|
event.special[this] = {
|
|
add: add,
|
|
remove: remove,
|
|
setup: function() {},
|
|
teardown: function() {}
|
|
};
|
|
});
|
|
};
|
|
})(jQuery);
|
|
(function($){
|
|
var isPhantom = /Phantom/.test(navigator.userAgent),
|
|
supportTouch = !isPhantom && "ontouchend" in document,
|
|
scrollEvent = "touchmove scroll",
|
|
// Use touch events or map it to mouse events
|
|
touchStartEvent = supportTouch ? "touchstart" : "mousedown",
|
|
touchStopEvent = supportTouch ? "touchend" : "mouseup",
|
|
touchMoveEvent = supportTouch ? "touchmove" : "mousemove",
|
|
data = function(event){
|
|
var d = event.originalEvent.touches ?
|
|
event.originalEvent.touches[ 0 ] :
|
|
event;
|
|
return {
|
|
time: (new Date).getTime(),
|
|
coords: [ d.pageX, d.pageY ],
|
|
origin: $( event.target )
|
|
};
|
|
};
|
|
|
|
/**
|
|
* @add jQuery.event.swipe
|
|
*/
|
|
var swipe = $.event.swipe = {
|
|
/**
|
|
* @attribute delay
|
|
* Delay is the upper limit of time the swipe motion can take in milliseconds. This defaults to 500.
|
|
*
|
|
* A user must perform the swipe motion in this much time.
|
|
*/
|
|
delay : 500,
|
|
/**
|
|
* @attribute max
|
|
* The maximum distance the pointer must travel in pixels. The default is 75 pixels.
|
|
*/
|
|
max : 75,
|
|
/**
|
|
* @attribute min
|
|
* The minimum distance the pointer must travel in pixels. The default is 30 pixels.
|
|
*/
|
|
min : 30
|
|
};
|
|
|
|
$.event.setupHelper( [
|
|
|
|
/**
|
|
* @hide
|
|
* @attribute swipe
|
|
*/
|
|
"swipe",
|
|
/**
|
|
* @hide
|
|
* @attribute swipeleft
|
|
*/
|
|
'swipeleft',
|
|
/**
|
|
* @hide
|
|
* @attribute swiperight
|
|
*/
|
|
'swiperight',
|
|
/**
|
|
* @hide
|
|
* @attribute swipeup
|
|
*/
|
|
'swipeup',
|
|
/**
|
|
* @hide
|
|
* @attribute swipedown
|
|
*/
|
|
'swipedown'], touchStartEvent, function(ev){
|
|
var
|
|
// update with data when the event was started
|
|
start = data(ev),
|
|
stop,
|
|
delegate = ev.delegateTarget || ev.currentTarget,
|
|
selector = ev.handleObj.selector,
|
|
entered = this;
|
|
|
|
function moveHandler(event){
|
|
if ( !start ) {
|
|
return;
|
|
}
|
|
// update stop with the data from the current event
|
|
stop = data(event);
|
|
|
|
// prevent scrolling
|
|
if ( Math.abs( start.coords[0] - stop.coords[0] ) > 10 ) {
|
|
event.preventDefault();
|
|
}
|
|
};
|
|
|
|
// Attach to the touch move events
|
|
$(document.documentElement).bind(touchMoveEvent, moveHandler)
|
|
.one(touchStopEvent, function(event){
|
|
$(this).unbind( touchMoveEvent, moveHandler);
|
|
// if start and stop contain data figure out if we have a swipe event
|
|
if ( start && stop ) {
|
|
// calculate the distance between start and stop data
|
|
var deltaX = Math.abs(start.coords[0] - stop.coords[0]),
|
|
deltaY = Math.abs(start.coords[1] - stop.coords[1]),
|
|
distance = Math.sqrt(deltaX*deltaX+deltaY*deltaY);
|
|
|
|
// check if the delay and distance are matched
|
|
if ( stop.time - start.time < swipe.delay && distance >= swipe.min ) {
|
|
var events = ['swipe'];
|
|
// check if we moved horizontally
|
|
if( deltaX >= swipe.min && deltaY < swipe.min) {
|
|
// based on the x coordinate check if we moved left or right
|
|
events.push( start.coords[0] > stop.coords[0] ? "swipeleft" : "swiperight" );
|
|
} else
|
|
// check if we moved vertically
|
|
if(deltaY >= swipe.min && deltaX < swipe.min){
|
|
// based on the y coordinate check if we moved up or down
|
|
events.push( start.coords[1] < stop.coords[1] ? "swipedown" : "swipeup" );
|
|
}
|
|
|
|
// trigger swipe events on this guy
|
|
$.each($.event.find(delegate, events, selector), function(){
|
|
this.call(entered, ev, {start : start, end: stop})
|
|
})
|
|
|
|
}
|
|
}
|
|
// reset start and stop
|
|
start = stop = undefined;
|
|
})
|
|
});
|
|
|
|
})(jQuery) |