Detecting the ‘Tap’ event on a Mobile touch device using javascript

tap-event

Currently we can use different types of events to control a touch gesture on a mobile device using javascript, but unfortunately they are not enough to detect all the huge amount of behaviours that an User could do with a touch gesture.
Some of the events that you can catch having everything under control are touchstart, touchmove, touchend and touchcancel.
In one of my projects I needed to detect the ‘Tap’ event that is a bit different from the ‘touchstart’ event *, so I found this solution that works pretty well, and here you can get the code.
*The Tap event should not be confused with the click because they are two things completely different
1 jQuery Solution

var getPointerEvent = function(event) {
    return event.originalEvent.targetTouches ? event.originalEvent.targetTouches[0] : event;
};
var $touchArea = $('#touchArea'),
    touchStarted = false, // detect if a touch event is sarted
    currX = 0,
    currY = 0,
    cachedX = 0,
    cachedY = 0;

//setting the events listeners
$touchArea.on('touchstart mousedown',function (e){
    e.preventDefault();
    var pointer = getPointerEvent(e);
    // caching the current x
    cachedX = currX = pointer.pageX;
    // caching the current y
    cachedY = currY = pointer.pageY;
    // a touch event is detected      
    touchStarted = true;
    $touchArea.text('Touchstarted');
    // detecting if after 200ms the finger is still in the same position
    setTimeout(function (){
        if ((cachedX === currX) && !touchStarted && (cachedY === currY)) {
            // Here you get the Tap event
            $touchArea.text('Tap');
        }
    },200);
});
$touchArea.on('touchend mouseup touchcancel',function (e){
    e.preventDefault();
    // here we can consider finished the touch event
    touchStarted = false;
    $touchArea.text('Touchended');
});
$touchArea.on('touchmove mousemove',function (e){
    e.preventDefault();
    var pointer = getPointerEvent(e);
    currX = pointer.pageX;
    currY = pointer.pageY;
    if(touchStarted) {
         // here you are swiping
         $touchArea.text('Swiping');
    }
   
});


Demo link [jQuery]

Some folks complained about my non pure Javascript solution so I thought to show how to use the previous snippet without the help any other framework.

2 If for whatever reasons you can’t use jQuery here you have also the Pure Javascript solution

// helpers
var $ = document.querySelector.bind(document),
    $$ = document.querySelectorAll.bind(document),
    getPointerEvent = function(event) {
        return event.targetTouches ? event.targetTouches[0] : event;
    },
   
    setListener = function (elm,events,callback) {
        var eventsArray = events.split(' '),
            i = eventsArray.length;
        while(i--){
            elm.addEventListener( eventsArray[i], callback, false );
        }
    };

var $touchArea = $('#touchArea'),
    touchStarted = false, // detect if a touch event is sarted
    currX = 0,
    currY = 0,
    cachedX = 0,
    cachedY = 0;

//setting the events listeners
setListener($touchArea,'touchstart mousedown',function (e){
    e.preventDefault();
    var pointer = getPointerEvent(e);
    // caching the current x
    cachedX = currX = pointer.pageX;
    // caching the current y
    cachedY = currY = pointer.pageY;
    // a touch event is detected      
    touchStarted = true;
    $touchArea.innerHTML = 'Touchstarted';
 
    // detecting if after 200ms the finger is still in the same position
    setTimeout(function (){
        if ((cachedX === currX) && !touchStarted && (cachedY === currY)) {
            // Here you get the Tap event
            $touchArea.innerHTML = 'Tap';
        }
    },200);
});
setListener($touchArea,'touchend mouseup touchcancel',function (e){
    e.preventDefault();
    // here we can consider finished the touch event
    touchStarted = false;
    $touchArea.innerHTML = 'Touchended';
});
setListener($touchArea,'touchmove mousemove',function (e){
    e.preventDefault();
    var pointer = getPointerEvent(e);
    currX = pointer.pageX;
    currY = pointer.pageY;
    if(touchStarted) {
         // here you are swiping
         $touchArea.innerHTML = 'Swiping';
    }
   
});


Demo Link [Pure Javascript]

3 Rock solid solution

If you need something more useful I wrote this supersmall script ( 1kb bytes minified ) Tocca.js to detect the tap and swipe events on any kind of device without too many ceremonies, just include the script into your html page and it will work like a charm.
Here there’s a basic usage example:

elm.addeventListener('tap',function(e){});
elm.addeventListener('dbltap',function(e){});
elm.addeventListener('swipeleft',function(e){});
elm.addeventListener('swiperight',function(e){});
elm.addeventListener('swipeup',function(e){});
elm.addeventListener('swipedown',function(e){});

// It works with jQuery as well:
$(elm).on('tap',function(e,data){});
$(elm).on('dbltap',function(e,data){});
$(elm).on('swipeleft',function(e,data){});
$(elm).on('swiperight',function(e,data){});
$(elm).on('swipeup',function(e,data){});
$(elm).on('swipedown',function(e,data){});

Download Tocca.js

12 Comments

    • Yeah you are right, but:

      1. jQuery is Javascript as well (and there is no reason to reinvent the wheel)
      2. The title of the post contains the keyword javascript just to specify that this code works only on a web environment
      3. This example is intentionally not a “vanilla polyfill”, but I am sure that any good frontend developer is able to convert it easily into pure JS (or to make a new one even better)

      I am sorry if this article wasn’t useful for you, but anyway thanks for your feedback :)
      Cheerio

  • so the main div (that holds every element) on my page must have an ID of ‘touchArea’ ? can I use that ID to my body tag?

  • Awesome! This is exactly what i am looking for… something what is Pure JavaScript because I am trying to keep mobile download time to a minimum!

    Thanks again!

  • Thanks man! I found this and solved my problem ! It work with jquery and pure javascript

  • Does your script support “longTap” and generic “swipe” events?

    Thanks

  • Hello, Guarini. I did not see if the script has like mouse hover but for touch devices.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>