Handling clicks for mobile platforms [UPDATED]

I’ve been doing a lot of work in Phonegap lately and I really like it.  However, one of the things I don’t like is that click events are really, really slow.  There’s a reason for this.  How does the browser know if it’s a click or the beginning of a move?  The answer to this is to bind your click events to the “touchend” event.

So, in JQuery you would previously do something like this.

1
target.bind('click', callback);

But that introduces the lag.  So I wrote a little function where instead of calling bind() I would call this function instead.  It would determine if it’s a desktop or mobile device and then either register the click event or the touchend event.

However, there is a problem with this.  The touchend call might come at the end of a move, in which case you don’t want to fire the click event’s callback.  So I wrote a little bit of code that checks for a move event and then unbinds the touchend event, storing the callback in the new function called at touchend.  If there is no move event the callback is called at touchend.  If the move event is not thrown the callback is re-bound at touchend so the next time a “click’ event is triggered the event will be there to handle it.

1
2
3
4
5
6
7
8
9
target.bind('touchmove', function() {
  var cb = callback;
  $(this).unbind('touchend', cb);
  $(this).bind('touchend', function() {
    var cbb = cb;
    $(this).bind('touchend', cbb);
    });
  });
target.bind('touchend', callback);

[EDIT]

It turns out that this is wrong.  One of the things that I neglected to see offhand was that this code was fine… IF only one touchmove event was fired.  However, if many were fired the callback would be added for each time touchmove was called.  If your finger was moving a lot, then a lot of calls to the callback would be executed on touch end.

Here is code that actually works properly.

1
2
3
4
5
6
7
8
9
10
11
12
target.bind('touchmove', function() {
  $(this).data('moved', true);
});
target.bind('touchend', function() {
  if ($(this).data('moved')) {
    $(this).data('moved', false);
    return;
  }
  $(this).data('moved', false);
  $(this).trigger('touchendnomove');
});
target.bind('touchendnomove', callback);

What this does differently is simply set a flag if a touchmove event is fired.  Then on touchend it checks to see if the flag has been set.  If not a CUSTOM event is fired.  This is important because we want $(this) to refer to the target when an event is fired.  This way we don’t have to do any magic to get the proper “this” association done and we don’t have the problem of those pesky touchmove events.

Related posts

One thought on “Handling clicks for mobile platforms [UPDATED]

  1. Phonegap can
    be considered for developing apps if you are short of time to deploy your apps
    across multiple platform. But when it comes to performance its not the one that
    can be recommended. Application that are not graphically heavy is a good fit. I
    did develop couple of apps in phonegap but found it be too slow. And to say
    phonegap is free is not totally true.
    http://www.mobilepundits.com/PhoneGap_Development.html

Leave a Comment