Created
February 24, 2012 15:17
-
-
Save desandro/1901569 to your computer and use it in GitHub Desktop.
addTap.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/*! | |
* addTap - helper function for adding click-ish event for touch devices | |
* by David DeSandro | |
*/ | |
/*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; | |
} | |
}; | |
window.addTap = addTap; | |
})( window ); | |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html> | |
<head> | |
<meta charset="utf-8"> | |
<title>addTap</title> | |
<meta name="viewport" content="width=device-width"> | |
<style> | |
body { | |
font-family: sans-serif; | |
} | |
#box { | |
width: 200px; | |
height: 300px; | |
background: red; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>addTap</h1> | |
<div id="box"></div> | |
<script src="addtap.js"></script> | |
<script> | |
window.onload = function() { | |
var box = document.getElementById('box'); | |
function onTap( event, cursor ) { | |
console.log( 'did tap', event, cursor.pageX, cursor.pageY ); | |
} | |
addTap( box, onTap, { moveableBuffer: 20 } ); | |
}; | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment