Ionic 5 - Ion-button click doesn't always trigger on Android tablet

@tonyawad88 so a few things to clarify here…

“default threshold”: There’s no timer or threshold set in Ionic for triggering a click event. As I stated above, we trigger the animation on touchStart, and the browser handles firing the click event. We do not intercept the click handlers and trigger them.

I’m don’t 100% agree with the suggestions of using @HostListener('touchend'), as that could cause more accidental triggers, which in my opinion is much worse.

Again, I want to point out that this behaviour can be replicated without Ionic and without and JS Framework involved.

If you test this on a mobile device and inspect the logs, you’ll see a touchStart, touchEnd, and click handlers being fired in the correct order. In some cases, the browser will opt to not fire a click event if it takes too long to release the button (or any clickable element). This is the browsers behaviour.

I recorded an example of this here.

You can see that the click events can star off firing, but you can see them stop if you hold on to the button just a bit too long.

@netkow
@mhartington

I don’t know if you read my message / tried my app to illustrate my point?

Try your click test video on Android, I don’t think you’re gonna see the same result in terms of events firing as you do on iOS. That’s the problem. You’re not seeing problematic behaviour on iOS, as expected. In order to make this a fair test, you need the same test on BOTH environments surely?

In some cases, the browser will opt to not fire a click event if it takes too long to release the button (or any clickable element). This is the browsers behaviour.

That’s exactly it!

@tonyawad88

So given that information, I think what we’re suggesting is that Ionic team provide (or you provide an alternative suggestion please) a way that we can OPTIONALLY hook into another event on Android to catch these clicks that are ignored, so that we can run them.

Lastly, if there really is nothing the Ionic team can do with this, then I think our only option is to try something like HammerJS and the press event for example: https://hammerjs.github.io/recognizer-press/

David, Yes, I tried your app, and I saw the same behaviour of click events not firing if the browser doesn’t think an action is a click.

Your assumption here is incorrect. I am testing this on Android as well as iOS.

I saw the behaviour describing by OP on iOS and Android, all without JS Frameworks, Ionic, or any library involved.

Pulling up some details from the Spec on a “click” event,

it MAY depend on the screen location or the delay between the press and release of the pointing device button.

Basically, if there’s a delay between press and the release, the browse may not fire the event.

I want to reiterate, what you are seeing, is expected behaviour as far as the browser is concerned. Given that this doesn’t appear to happen besides in a few cases (where users hold a button too long) I’m not sure there’s anything from Ionic that can be done.

I don’t recommend using hammerJS, as it attached to every event (so can of worms as far as dependability is concerned). There’s long-press snippets/libs out there if you really feel like you need them, but again, this is not a rampant issue or else we’d be seeing more issue reports.

Also going to add, @Daveshirman, you do not need to tag Ionic folks in every post. Those who replied to the thread already get notified.

Very useful info, great thanks Mike.

Was just tagging you as to draw attention to a particular part of the reply to facilitate the conversation between us all, as you have just done with me.:+1:

Have a good holiday everyone!

@tonyawad88 Just FYI - I had another issue I was trying to fix today (keeping the keyboard open after pressing a button) and have observed (in Android) that by binding to the touchend event, I am able to have the desired behaviour we were looking for, where “clicks” or “taps” are not ignored.

I’ve not done extensive testing, but essentially this is my code today:

Note: This is from a chat page, where btnSend is the send message button.

  applyKeyboardStayOpenFix() {
    let el = document.getElementById('btnSend');
    if (!el) { return; }

    el.addEventListener('click', (e) => { this.stopBubble(e); });
    el.addEventListener('mousedown', (e) => { this.stopBubble(e); });
    el.addEventListener('touchdown', (e) => { this.stopBubble(e); });
    el.addEventListener('touchmove', (e) => { this.stopBubble(e); });
    el.addEventListener('touchstart', (e) => { this.stopBubble(e); });
    
    //Triggered by a phone
    el.addEventListener('touchend', (e) => { this.stopBubble(e); this.sendMessage(); });
    //Triggered by the browser
    el.addEventListener('mouseup', (event) => { this.sendMessage(); });
  }

  stopBubble(event) {
    event.preventDefault(); 
    event.stopPropagation(); //Stops event bubbling
  }

Hope this helps.

That sounds great! Thank you for the info and for sharing.

This should help take care of the sensitive buttons. Any idea if the ripple still trigger?

Yes the ripple still triggers. I’m thinking you could wrap this into a service / custom component, so you could easily apply this fix to any critical buttons / interface elements in your app.