Forums

The forums ran from 2008-2020 and are now closed and viewable here as an archive.

Home Forums JavaScript Touch device ghost click triggers on different element Reply To: Touch device ghost click triggers on different element

#253039
Shikkediel
Participant

Okay, small edits don’t seem to be allowed… let me post again.

Original “ghost click” issue – an old Android bug, sort of solved…

But here’s the final code I’m using to create a page:tap, eliminating the more commonly known ghost click that comes from touch events being emulated:

function swiftClick(aim) {

  $(document).on('mousedown touchstart click', aim, {}, function(e) {

    var mean = $(e.currentTarget), info = e.data;

    if (e.type == 'mousedown' && (e.which != 1 || info.hit)) return;
    if (e.type == 'click') {
      delete info.hit;
      return false;
    }

    info.peg = Date.now();

    mean.one('mouseup touchend', function(e) {

      if (e.type == 'touchend') info.hit = true;
      else if (info.hit) return;
      if (Date.now()-info.peg > 300) return;
      mean.trigger('page:tap');
    });
  })
  .on('page:tap', aim, function() {

    if ($(this).is('a')) location = this.href;
  });
}

Usage:

swiftClick('.something');

$('.something').on('page:tap', function() { // do whatever });

Using persistent event data’s a bit nicer than adding classes. Clicks on links will have their default behaviour blocked and get redirected by the script. Subsequent touchstart-touchend or mousedown-mouseup will not trigger a page:tap if it took longer than 300ms.

It’s going a bit out of the scope of the original issue but the custom event I put together has a shortcoming as well that is in the same sphere. Which is that if you happen to touch an element with the event listener and start scrolling, after removing the finger the event might get triggered.

In fact, default touchcancel behaviour on many browsers will make the touchend not fire in that case which is quite convenient. But the 300ms time limit should also mostly solve it.