2013-05-22 4 views
5

Sto riscontrando problemi con la combinazione di trasformazioni CSS e test di hit evento tocco. Questo si riproduce solo per me in Chrome su Android 4 (stabile e beta). Sia iOS Safari che il desktop Chrome con emulazione touch sembrano funzionare correttamente.Android 4 Chrome ha riscontrato un problema di test sugli eventi di tocco dopo la trasformazione CSS

Sono quasi certo che questo deve essere un bug, quindi penso che cerco soprattutto soluzioni alternative qui.

Il problema è che il test di successo per il tocco sembra funzionare solo per il punto in cui l'elemento si trovava prima della trasformazione, non nella posizione finale. È possibile vedere un esempio sulla mia jsfiddle (solo su Android 4 Chrome):

jsfiddle: http://jsfiddle.net/LfaQq/ schermo intero: http://jsfiddle.net/LfaQq/embedded/result/

Se si trascina il blue box a metà strada verso il basso dello schermo e rilasciarlo scatterà di nuovo a la cima. Ora, se provi a trascinare nuovamente dalla metà superiore della pagina, nessun tocco verrà registrato. Gli eventi tattili non sono nemmeno sparati sull'elemento. Tuttavia, se si tenta di toccare la parte inferiore dell'elemento, funziona correttamente. Puoi quindi provare a spostarlo dal basso e osservare che il test dei colpi non funziona più sul fondo, ma funziona in alto.

Questo è come sto gestendo gli eventi:

function handleTouch(e) { 

    console.log("handle touch") 

    e.preventDefault(); 

    switch(e.type){ 
     case 'touchstart': 
      console.log("touchstart"); 
      touchOriginY = e.targetTouches[0].screenY; 
      break; 
     case 'touchmove': 
      console.log("touchmove"); 
      el.innerHTML = e.targetTouches[0].screenY; 
      var p = e.targetTouches[0].screenY - touchOriginY; 
      el.style[TRANSFORM] = 'translate3d(0,' + p + 'px' + ',0)'; 
      break; 
     case 'touchcancel': 
      console.log("touchcancel"); 
      // Fall through to touchend 
     case 'touchend': 
      //console.log("touchend"); 
      //el.style[TRANSITION] = '.4s ease-out'; 
      el.style[TRANSFORM] = 'translate3d(0,0,0)'; 
      break; 
    } 

} 

el.addEventListener('touchstart', handleTouch); 
el.addEventListener('touchend', handleTouch); 
el.addEventListener('touchmove', handleTouch); 
el.addEventListener(TRANSITION_END, function(e) { 
    console.log("transition end") 
    el.style[TRANSITION] = ''; 
}); 

Non ho alcun problema con le trasformazioni in touchmove, come quelli non sono nuovi tocchi da rilevare in ogni modo.

Qualche suggerimento?

+0

Penso di essermi alquanto sbloccato su questo per il momento. La rimozione dell'aggiornamento HTML interno da touchmove interrompe la cattiva qualità dell'obiettivo colpito. Spero che questo non ritorni a mordermi quando ho legittimamente bisogno di aggiornare il contenuto all'interno dell'elemento in un secondo momento. –

risposta

8

Questo è un bug insolito in Chrome.

In sostanza i target di successo per un elemento vengono registrati durante un passaggio di layout dal browser. Ogni volta che si imposta innerHTML, il browser si riavvia e l'ultima volta che viene eseguita, è prima che venga attivato l'evento touchend. Ci sono un paio di modi per aggirarlo:

OPZIONE 1: È possibile impostare un gestore di tocco sull'elemento del corpo e controllare il target dell'evento di tocco per vedere se sta toccando il blocco rosso. Punta del berretto a Paul Lewis per questo approccio.

http://jsfiddle.net/FtfR8/5/

var el = document.body; 
var redblock = $('.splash-section'); 

function handleTouch(e) { 

    console.log("handle touch") 
    if(e.target != redblock) { 
     return; 
    } 

    .... 

OPZIONE 2: Impostare un tocco di richiamata vuota sul documento sembra risolvere il problema, come pure - secondo alcuni delle segnalazioni di bug legati, questo fa sì che il rilevamento del contatto per essere fatto sul thread principale che è un successo sulle prestazioni ma calcola correttamente i bersagli colpiti.

http://jsfiddle.net/LfaQq/2/

document.body.addEventListener('touchstart', function(){}); 

OPZIONE 3: Impostare innerHTML dopo la transizione si è concluso per forzare una Ridefinisci layout:

el.addEventListener(TRANSITION_END, function(e) { 
    console.log("trans end - offsettop:" + el.offsetTop); 
    el.style[TRANSITION] = ''; 
    el.innerHTML = 'Relayout like a boss!'; 
}); 

ho creato un bug report qui e Rick Byers ha collegato ad un relativo bug con informazioni aggiuntive: https://code.google.com/p/chromium/issues/detail?id=253456&thanks=253456&ts=1372075599

+1

"OPZIONE 2" funziona come un incantesimo, grazie. –