How to bind ‘touchstart’ and ‘click’ events but not respond to both?

I’m working on a mobile web site that has to work on a variety of devices. The ones giving me a headache at the moment are BlackBerry.

We need to support both keyboard clicks as well as touch events.

Ideally I’d just use:

$thing.click(function(){...})

but the issue we’re running into is that some of these blackberry devices have a very annoying delay from the time of the touch to it triggering a click.

The remedy is to instead use touchstart:

$thing.bind('touchstart', function(event){...})

But how do I go about binding both events, but only firing one? I still need the click event for keyboard devices, but of course, don’t want the click event firing if I’m using a touch device.

A bonus question: Is there anyway to do this and additionally accommodate browsers that don’t even have a touchstart event? In researching this, it looks like BlackBerry OS5 doesn’t support touchstart so will also need to rely on click events for that browser.

ADDENDUM:

Perhaps a more comprehensive question is:

With jQuery, is it possible/recommended to handle both touch interactions and mouse interactions with the same bindings?

Ideally, the answer is yes. If not, I do have some options:

  1. We use WURFL to get device info so could create our own matrix of devices. Depending on the device, we’ll use touchstart OR click.

  2. Detect for touch support in the browser via JS (I need to do some more research on that, but it seems like that is doable).

However, that still leaves one issue: what about devices that support BOTH. Some of the phones we support (namely the Nokias and BlackBerries) have both touch screens and keyboards. So that kind of takes me full circle back to the original question…is there a way to allow for both at once somehow?

37 Answers
37

Update: Check out the jQuery Pointer Events Polyfill project which allows you to bind to “pointer” events instead of choosing between mouse & touch.


Bind to both, but make a flag so the function only fires once per 100ms or so.

var flag = false;
$thing.bind('touchstart click', function(){
  if (!flag) {
    flag = true;
    setTimeout(function(){ flag = false; }, 100);
    // do something
  }

  return false
});

Leave a Comment