Phonegap 2.4.0 with Android 4.2 - strange double click behaviour

前端 未结 5 1023
暖寄归人
暖寄归人 2020-12-30 08:03

I\'m using phonegap 2.4.0 to create an Android and iOS App.

Now I recognized that the onclick event in links is fired twice inside the Android App using Android 4.2.

相关标签:
5条回答
  • 2020-12-30 08:30

    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);
        }
    }
    
    0 讨论(0)
  • 2020-12-30 08:32

    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

    0 讨论(0)
  • 2020-12-30 08:37

    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');
    });
    
    0 讨论(0)
  • 2020-12-30 08:40

    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...      
    }
    
    0 讨论(0)
  • 2020-12-30 08:46

    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);
    
    0 讨论(0)
提交回复
热议问题