|  | /*! | 
        
          |  | * addTap v1.0.00 - helper function for adding click-ish events for touch devices | 
        
          |  | * by David DeSandro | 
        
          |  | * https://gist.github.com/1901569 | 
        
          |  | */ | 
        
          |  |  | 
        
          |  | /*jshint undef: true, forin: false, browser: true */ | 
        
          |  |  | 
        
          |  | (function( window, undefined ){ | 
        
          |  |  | 
        
          |  | var isTouch = 'ontouchstart' in window; | 
        
          |  | var cursorStartEvent = isTouch ? 'touchstart' : 'mousedown'; | 
        
          |  | var cursorMoveEvent = isTouch ? 'touchmove' : 'mousemove'; | 
        
          |  | var cursorEndEvent = isTouch ? 'touchend' : 'mouseup'; | 
        
          |  |  | 
        
          |  | // -------------------------- addTap -------------------------- // | 
        
          |  |  | 
        
          |  | function addTap( elem, onTap, options ) { | 
        
          |  |  | 
        
          |  | var handler = new addTap.Handler( onTap, options ); | 
        
          |  |  | 
        
          |  | elem.addEventListener( cursorStartEvent, handler, false ); | 
        
          |  |  | 
        
          |  | } | 
        
          |  |  | 
        
          |  | // -------------------------- TapHandler -------------------------- // | 
        
          |  |  | 
        
          |  | addTap.Handler = function( onTap, options ) { | 
        
          |  | // bail out if onTap callback is not set | 
        
          |  | if ( !onTap ) { | 
        
          |  | return; | 
        
          |  | } | 
        
          |  |  | 
        
          |  | // set onTap callback | 
        
          |  | this.onTap = onTap; | 
        
          |  |  | 
        
          |  | // set options | 
        
          |  | this.options = {}; | 
        
          |  | // set defaults | 
        
          |  | for ( var prop in addTap.Handler.defaults ) { | 
        
          |  | this.options[ prop ] = addTap.Handler.defaults[ prop ]; | 
        
          |  | } | 
        
          |  | // overwrite with passed-in options | 
        
          |  | for ( prop in options ) { | 
        
          |  | this.options[ prop ] = options[ prop ]; | 
        
          |  | } | 
        
          |  |  | 
        
          |  | }; | 
        
          |  |  | 
        
          |  | addTap.Handler.defaults = { | 
        
          |  | moveableBuffer: 3 | 
        
          |  | }; | 
        
          |  |  | 
        
          |  | addTap.Handler.prototype = { | 
        
          |  |  | 
        
          |  | handleEvent: function( event ) { | 
        
          |  | if ( this[ event.type ] ) { | 
        
          |  | this[ event.type ]( event ); | 
        
          |  | } | 
        
          |  | }, | 
        
          |  |  | 
        
          |  | // ----- start ----- // | 
        
          |  |  | 
        
          |  | mousedown: function( event ) { | 
        
          |  | this.cursorStart( event ); | 
        
          |  | }, | 
        
          |  |  | 
        
          |  | touchstart: function( event ) { | 
        
          |  | // bail out if we already have a touch | 
        
          |  | if ( this.touch ) { | 
        
          |  | return; | 
        
          |  | } | 
        
          |  | // get first changedTouch | 
        
          |  | this.touch = event.changedTouches[0]; | 
        
          |  | this.cursorStart( this.touch ); | 
        
          |  | }, | 
        
          |  |  | 
        
          |  | cursorStart: function( cursor ) { | 
        
          |  | // set start point | 
        
          |  | this.startPoint = { | 
        
          |  | x: cursor.pageX, | 
        
          |  | y: cursor.pageY | 
        
          |  | }; | 
        
          |  |  | 
        
          |  | // listen for move and end events | 
        
          |  | window.addEventListener( cursorMoveEvent, this, false ); | 
        
          |  | window.addEventListener( cursorEndEvent, this, false ); | 
        
          |  | }, | 
        
          |  |  | 
        
          |  | // ----- move ----- // | 
        
          |  |  | 
        
          |  | mousemove: function( event ) { | 
        
          |  | this.cursorMove( event ); | 
        
          |  | }, | 
        
          |  |  | 
        
          |  | touchmove: function( event ) { | 
        
          |  | var matchedTouch = this.getMatchedTouch( event ); | 
        
          |  | if ( matchedTouch ) { | 
        
          |  | this.cursorMove( matchedTouch ); | 
        
          |  | } | 
        
          |  | }, | 
        
          |  |  | 
        
          |  | getMatchedTouch: function( event ) { | 
        
          |  | var touch, matchedTouch; | 
        
          |  | // iterate through touches | 
        
          |  | for ( var i=0, len = event.changedTouches.length; i < len; i++ ) { | 
        
          |  | touch = event.changedTouches[i]; | 
        
          |  | // get matched touch | 
        
          |  | if ( touch.identifier === this.touch.identifier ) { | 
        
          |  | matchedTouch = touch; | 
        
          |  | break; | 
        
          |  | } | 
        
          |  | } | 
        
          |  | return matchedTouch; | 
        
          |  | }, | 
        
          |  |  | 
        
          |  | cursorMove: function( cursor ) { | 
        
          |  | var moveX = cursor.pageX - this.startPoint.x; | 
        
          |  | var moveY = cursor.pageY - this.startPoint.y; | 
        
          |  |  | 
        
          |  | // check if touch has moved outside buffer zone | 
        
          |  | if ( Math.abs( moveX ) > this.options.moveableBuffer || | 
        
          |  | Math.abs( moveY ) > this.options.moveableBuffer | 
        
          |  | ) { | 
        
          |  | // if outside, then remove listeners, so onTap won't be triggered | 
        
          |  | this.reset(); | 
        
          |  | } | 
        
          |  |  | 
        
          |  | }, | 
        
          |  |  | 
        
          |  | // ----- end ----- // | 
        
          |  |  | 
        
          |  | mouseup: function( event ) { | 
        
          |  | this.cursorEnd( event, event ); | 
        
          |  | }, | 
        
          |  |  | 
        
          |  | touchend: function( event ) { | 
        
          |  | var matchedTouch = this.getMatchedTouch( event ); | 
        
          |  | if ( matchedTouch ) { | 
        
          |  | this.cursorEnd( event, matchedTouch ); | 
        
          |  | } | 
        
          |  | }, | 
        
          |  |  | 
        
          |  | cursorEnd: function( event, cursor ) { | 
        
          |  | // trigger onTap callback | 
        
          |  | this.onTap( event, cursor ); | 
        
          |  | this.reset(); | 
        
          |  | }, | 
        
          |  |  | 
        
          |  | reset: function() { | 
        
          |  | window.removeEventListener( cursorMoveEvent, this, false ); | 
        
          |  | window.removeEventListener( cursorEndEvent, this, false ); | 
        
          |  | delete this.touch; | 
        
          |  | } | 
        
          |  |  | 
        
          |  | }; | 
        
          |  |  | 
        
          |  | // publicize | 
        
          |  | window.addTap = addTap; | 
        
          |  |  | 
        
          |  | })( window ); |