Phonegap 2.4.0 with Android 4.2 - strange double click behaviour

梦想与她 提交于 2019-11-30 06:59:47

Using a temporary solution from scirra.com

last_click_time = new Date().getTime();
document.addEventListener('click', function (e) {
    click_time = e['timeStamp'];
    if (click_time && (click_time - last_click_time) < 1000) {
        e.stopImmediatePropagation();
        e.preventDefault();
        return false;
    }
    last_click_time = click_time;
}, true);

I handled my similar situation very closely to Soulwax's solution, however I didn't want to hinder fast clicks by the user by keeping track of time intervals. Instead, I simply track the event type in the link's data object and if it's trying to handle a click immediately after a touchstart I ignore that call.

$('.link').on('touchstart click', function(e){
  e.preventDefault();

  //Prevent against handling a click immediately after touchstart.
  if(e.type == "click" && $(this).data("lastTouch") == "touchstart"){
    e.stopImmediatePropagation();
    return false;
  }
  $(this).data("lastTouch", e.type);

  $('.nav-bar').toggleClass('active');
});

I think the reason of these double/multiple clicks are malfunctioning hardware accelerations, I'm experiencing simultaneous clicks + propagation's, propagation's are easy to prevent, however since third argument of addEventListener isn't respected in my case, I can't prevent double click even with the previously answered code, here is what I ended up using

function cw(event) // click wall
{ try {
    click_time_cw = (new Date()).getTime();
    if (click_time_cw && (click_time_cw - last_click_time_cw) < 350) {
        event.stopImmediatePropagation();
        event.preventDefault();
        add_log('prevented misclick [CW] '+(click_time_cw - last_click_time_cw));
        return true;
    }
    last_click_time_cw = click_time_cw;
    event.stopImmediatePropagation();
    event.stopPropagation();
    return false;
} catch(e){ add_alert(e,"stpr"); } }

you also have to initialize last_click_time_cw=(new Date()).getTime() somewhere

this is an example onclick:

<button class="btn" onclick="if(cw(event)) return true; onclick_logic()">something</button>

it might seem like a lot of work and an unpleasant/ugly fix, but click problems have been haunting me for months, it seems like this is what I should've done from the begining

My fix was a little bit different. I've used touchend instead click event listener, because click doesn't fire each time it's needed. Let's say you click a button, the click event listener is fired, but if you click that button again it is not.

It happens to any kind of DOM element. My environment is:

  • jQuery 1.9.1;
  • jQM 1.3.2;
  • Phonegap 3.5.0-0.21.14.

Here is my code:

if (window.cordova) {
    // hack to avoid double tap
    var lastTapTime = new Date().getTime();
    function tryToAvoidDoubleTap(e){
        var tapTime = e["timeStamp"];
        if (tapTime && (tapTime - lastTapTime) < 300) {
            // prevent double tap to happen
            e.stopImmediatePropagation();
            e.preventDefault();
            // jQM button handling
            if ($('.ui-btn').length)
                $('.ui-btn').removeClass('ui-btn-active');
            return false;
        }
        lastTapTime = tapTime;
    }

    // Wait for PhoneGap to load
    document.addEventListener("deviceready", onDeviceReady, false);

    // PhoneGap is ready
    function onDeviceReady() {
        document.addEventListener("touchend", tryToAvoidDoubleTap, true);
    }
}

I was facing the exact same issue, but my app/game needed the user to be able to double tap, on touchstart. So the scirra solution mentioned above wasn't usable as a required delay of 500 or 1000 ms kills the doubletap.

After some digging I noticed a difference between the first (user) tap and the second (bug) tap:

event.originalEvent.touches 

isn't available in the second bug tap. So I wrote this bug detection helper which solved my case:

function isDoubleTapBug (e) {
  // only handle touch events (in case your listener works on mouse events too)
  if (!'ontouchstart' in document.documentElement)) 
    return false;
  if (!e.originalEvent.touches) {
    e.preventDefault();
    e.stopPropagation();
    return true; // indicate to caller that it's a bug
  }
  return false;
}

Then in your listener, do this:

document.addEventListener('touchstart', function (e) {
  if (isDoubleTapBug(e))
    return false;
  // now do your actual event handling stuff...      
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!