Skip to content

Instantly share code, notes, and snippets.

@desandro
Created February 24, 2012 15:17
Show Gist options
  • Save desandro/1901569 to your computer and use it in GitHub Desktop.
Save desandro/1901569 to your computer and use it in GitHub Desktop.
addTap.js

addTap

helper function for adding click-ish events for touch devices

Usage

addTap( elem, onTap, options );

// for example
var box = document.getElementById('box');

function onTap( event, cursor ) {
  // event is the event objects
  // cursor is the event or touch object, containing pageX and pageY
  console.log( event.type + ' just happened. At ' +
    cursor.pageX + ' ' cursor.pageY )
}

addTap( box, onTap, {
  moveableBuffer: 10
});

Options

  • moveableBuffer: how far in both directions of X and Y can the cursor move around, and still trigger a tap event
/*!
* 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 );
<!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