(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)