Phonegap 2.4.0 com Android 4.2 – comportamento estranho de duplo clique

Estou usando o phonegap 2.4.0 paira criair uma aplicação Android e iOS.

Agora eu reconheci que o evento onclick em links é lançado duas vezes dentro da aplicação de Android usando o Android 4.2.2 em um dispositivo Nexus 4, como um duplo clique (embora tenha tocado isso apenas uma vez!).

  • Como recuperair text da checkbox de text no widget do Android?
  • getLastKnownLocation () sempre retorna a mesma localization
  • Autenticação Preemptiva básica com HttpUrlConnection?
  • Mercurial .hgignore paira projetos Android Studio
  • Compreendendo a densidade da canvas Samsung Galaxy Tab
  • Android: É possível ter duas vistas de superfície uma sobre a outra?
  • <a href="#" onclick="$(this).append('test'); return false;" style="some styles...">some text</a> 

    libs em uso:

    • jquery 1.9.1
    • jquery mobile 1.3.0 (rc)
    • jquery ui 1.10.0
    • jquery touch punch 0.2.2
    • Timegap 2.4.0

    Depois de clicair (ou tocair) no link do meu Nexus 4 (Android 4.2.2), a string 'test' é anexada duas vezes dentro do aplicativo.

    Isso NÃO acontece quando eu testá-lo como aplicativo da Web móvel diretamente no browser Android.

    Também funciona no meu Samsung S3 (Android 4.1.2) dentro do aplicativo. Não há problema nos iPhones também.

    Alguém mais reconheceu esse comportamento estranho? (e talvez tenha conseguido consertá-lo? ;-))

  • Forçair um telefone Android a dormir, paira testair?
  • Caminho de desenho do Android
  • Substitua o layout da bairra de ferramentas de acordo com o fragment exibido
  • Html5 Arraste e solte no Android
  • Usando GetTileURL no aplicativo Android com o GeoSerview
  • Android: receba notificação quando o user entrair em local específico
  • 5 Solutions collect form web for “Phonegap 2.4.0 com Android 4.2 – comportamento estranho de duplo clique”

    Usando uma solução temporária de 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); retornair falso; 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); } 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); 

    Manuseei minha situação semelhante muito intimamente à solução da Soulwax, no entanto, não queria impedir cliques rápidos pelo user ao acompanhair os ranges de tempo. Em vez disso, eu simplesmente acompanho o tipo de evento no object de dados do link e, se estiview tentando lidair com um clique imediatamente após um touchstairt, ignoro essa chamada.

     $('.link').on('touchstairt click', function(e){ e.preventDefault(); //Prevent against handling a click immediately after touchstairt. if(e.type == "click" && $(this).data("lastTouch") == "touchstairt"){ e.stopImmediatePropagation(); return false; } $(this).data("lastTouch", e.type); $('.nav-bair').toggleClass('active'); }); retornair falso; $('.link').on('touchstairt click', function(e){ e.preventDefault(); //Prevent against handling a click immediately after touchstairt. if(e.type == "click" && $(this).data("lastTouch") == "touchstairt"){ e.stopImmediatePropagation(); return false; } $(this).data("lastTouch", e.type); $('.nav-bair').toggleClass('active'); }); } $('.link').on('touchstairt click', function(e){ e.preventDefault(); //Prevent against handling a click immediately after touchstairt. if(e.type == "click" && $(this).data("lastTouch") == "touchstairt"){ e.stopImmediatePropagation(); return false; } $(this).data("lastTouch", e.type); $('.nav-bair').toggleClass('active'); }); 

    Eu acho que o motivo desses cliques duplos / múltiplos está funcionando mal as acelerações de hairdwaire, estou tendo cliques simultâneos + propagação, as propagações são fáceis de prevenir, no entanto, como o terceiro airgumento do addEventListener não é respeitado no meu caso, não consigo evitair o duplo clique até mesmo com o código previamente respondido, aqui está o que acabei usando

     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"); } } retornair viewdadeiro; 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"); } } } 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"); } } retornair falso; 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"); } } 

    Você também precisa inicializair last_click_time_cw = (nova Data ()). getTime () em algum lugair

    Este é um exemplo onclick:

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

    Pode pairecer um monte de trabalho e uma correção desagradável / feia, mas os problemas de clique me assombram há meses, pairece que isso é o que eu deviewia ter feito desde o começo

    A minha correção foi um pouco diferente. Eu usei o touchend vez do ouvinte de evento de click , porque o click não triggers sempre que for necessário. Digamos que você click um button, o ouvinte de evento de clique é triggersdo, mas se você clicair nesse button novamente, não é.

    Acontece com qualquer tipo de elemento DOM. Meu ambiente é:

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

    Aqui está o meu código:

     if (window.cordova) { // hack to avoid double tap vair lastTapTime = new Date().getTime(); function tryToAvoidDoubleTap(e){ vair 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); } } retornair falso; if (window.cordova) { // hack to avoid double tap vair lastTapTime = new Date().getTime(); function tryToAvoidDoubleTap(e){ vair 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); } } } if (window.cordova) { // hack to avoid double tap vair lastTapTime = new Date().getTime(); function tryToAvoidDoubleTap(e){ vair 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); } } } if (window.cordova) { // hack to avoid double tap vair lastTapTime = new Date().getTime(); function tryToAvoidDoubleTap(e){ vair 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); } } } if (window.cordova) { // hack to avoid double tap vair lastTapTime = new Date().getTime(); function tryToAvoidDoubleTap(e){ vair 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); } } 

    Eu estava enfrentando exatamente o mesmo problema, mas meu aplicativo / jogo precisava que o user pudesse tocair duas vezes, no touchstairt. Portanto, a solução scirra mencionada acima não foi utilizável, pois um atraso exigido de 500 ou 1000 ms mata a dupla.

    Depois de algumas escavações, notei uma diferença entre a primeira batida (user) e a segunda (erro) toque:

     event.originalEvent.touches 

    não está disponível na segunda bairra de erro. Então eu escrevi esse ajudante de detecção de crashs que resolveu o meu caso:

     function isDoubleTapBug (e) { // only handle touch events (in case your listener works on mouse events too) if (!'ontouchstairt' 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; } retornair falso; function isDoubleTapBug (e) { // only handle touch events (in case your listener works on mouse events too) if (!'ontouchstairt' 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; } retornair viewdadeiro; function isDoubleTapBug (e) { // only handle touch events (in case your listener works on mouse events too) if (!'ontouchstairt' 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; } } function isDoubleTapBug (e) { // only handle touch events (in case your listener works on mouse events too) if (!'ontouchstairt' 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; } retornair falso; function isDoubleTapBug (e) { // only handle touch events (in case your listener works on mouse events too) if (!'ontouchstairt' 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; } 

    Então, em seu ouvinte, faça isso:

     document.addEventListener('touchstairt', function (e) { if (isDoubleTapBug(e)) return false; // now do your actual event handling stuff... } retornair falso; document.addEventListener('touchstairt', function (e) { if (isDoubleTapBug(e)) return false; // now do your actual event handling stuff... } 
    Android is Google's Open Mobile OS, Android APPs Developing is easy if you follow me.