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

#252915
Shikkediel
Participant

Okay, I think I finally got to the bottom of this. There are two issues crossing each other. The first one is the more generally known ghost clicks, these seem to be handled nicely from where I got so far. The other issue is very Android specific and hard to describe. After a custom (click) event that deals with both touch and mouse and then hiding the element in question, the emulated mouse events caused by touch devices are triggered on the element that was underneath it. And not on the element itself. This is clearly a bug that needs an approach of it’s own – I chose to use elementFromPoint to determine which element is underneath and temporarily disable pointer events on it. Strangely enough links still get highlighted because of an emulated hover effect now and then but I can live with that.

So I’m sending some extra data with the custom page:tap event (did I ever mention how excellent this part of jQuery is?), namely the touch coordinates:

var nub = $('html'), swiftClick = function(aim) {

  $(bud).on('mousedown touchstart', aim, function(e) {

    if (e.type == 'mousedown' && e.which != 1) return;

    var mean = $(e.currentTarget);

    if (e.type == 'touchstart') {
      var feel = e.originalEvent.touches[0],
      region = [feel.screenX, feel.screenY];
    }

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

      var hit = nub.hasClass('punch');

      if (e.type == 'touchend' && !hit) nub.addClass('punch');
      else if (hit) return;

      mean.trigger({type: 'page:tap', put: region});
    });
}).on('click', aim, function() {

  if (!nub.hasClass('punch')) return;
  nub.removeClass('punch');
  return false;
});
}

Also troublesome on Android, nothing but screenX and screenY did the trick.

Next step is to listen to the custom event, check the coordinates and “silence” the element below if it is a link (closing the modal would trigger a redirect before):

var goal = '#anelement';

swiftClick(goal);

$(goal).on('page:tap', function(e) {

  if (!e.put) return;

  var below = document.elementFromPoint(e.put[0], e.put[1]),
  sample = $(below).closest('a');

  if (!sample) return;

  sample.addClass('silent');

  setTimeout(function() {
    sample.removeClass('silent');
  }, 500);
});
.silent {
  pointer-events: none;
}

Very circumventive but that’s old Android for ya…