2013-05-22 1 views
5

CSS 변환 및 터치 이벤트 적중 테스트와 관련된 문제가 있습니다. 이것은 Android 4 (안정 및 베타)의 Chrome에서만 나에게 적합합니다. iOS Safari와 터치 에뮬레이션을 사용하는 Chrome 데스크톱은 잘 작동하는 것으로 보입니다.Android 4 CSS 변형 후 터치 이벤트에 대한 Chrome 히트 테스트 문제

나는 이것이 버그가되어야한다는 점에서 거의 긍정적이다. 그래서 나는 대체로 여기서 해결 방법을 찾고 있다고 생각한다.

터치의 히트 테스트는 요소가 변형 이전의 위치가 아닌 최종 위치에서만 작동하는 것처럼 보입니다. 당신은 (Android 만 4 크롬에) 내 jsfiddle에 예를 볼 수 있습니다

jsfiddle : http://jsfiddle.net/LfaQq/ 전체 화면 : 화면 아래 파란색 상자 절반 방법을 끌어다 놓으면 http://jsfiddle.net/LfaQq/embedded/result/

그것을 다시 스냅됩니다 상단. 이제 페이지 위쪽에서 다시 드래그하면 아무런 터치도 등록되지 않습니다. 터치 이벤트는 요소에서 실행되지 않습니다. 그러나 요소의 아래쪽을 터치하려고하면 잘 동작합니다. 그런 다음 아래에서 위로 이동하여 시도 할 수 있으며 적중 테스트가 더 이상 하단에서 작동하지 않지만 상단에서 작동한다는 것을 관찰 할 수 있습니다.

이 내가 이벤트를 처리하고있어 방법은 다음과 같습니다 사람들은 어쨌든 검출 할 수있는 새로운 감각이 아니기 때문에

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] = ''; 
}); 

는 내가하는 TouchMove의 변환에 문제가 없습니다.

제안 사항?

+0

나는 당분간 이것에 대해 다소 자신을 차단했다고 생각합니다. touchmove에서 innerHTML 업데이트를 제거하면 적중 횟수가 나 빠지게됩니다. 나중에 요소 내부의 내용을 합법적으로 업데이트해야 할 때 이것이 나를 물지 않기를 바랍니다. –

답변

8

이것은 Chrome의 일반적인 버그입니다.

기본적으로 요소의 적중 대상은 브라우저가 레이아웃을 통과하는 동안 기록됩니다. innerHTML을 설정할 때마다 브라우저가 다시 레이아웃을 수행하고 마지막으로이 작업이 완료되면 touchend 이벤트가 시작됩니다. 그 주위에 몇 가지 방법이 있습니다 :

옵션 1 : body 요소에 터치 핸들러를 설정하고 터치 이벤트의 대상이 빨간색 블록을 터치하는지 확인하십시오. 이 접근법에 대한 폴 루이스 (Paul Lewis)의 모자 팁.

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; 
    } 

    .... 

옵션 2 : 문서의 빈 터치 콜백뿐만 아니라 문제를 해결하기 위해 보인다 설정 - 링크 된 버그 리포트의 일부에 따르면,이 히트 테스트가에서 수행되도록 주 스레드는 성능에 치명적이지만 적중 대상을 적절하게 계산합니다.

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

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

옵션 3 : 설정 innerHTML을 전환은 레이아웃 작업 강제로 종료 된 후 : 내가 여기에 버그 리포트를 생성 한 릭 바이어스가 관련 연결했다

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

을 추가 정보가있는 버그 : https://code.google.com/p/chromium/issues/detail?id=253456&thanks=253456&ts=1372075599

+1

"OPTION 2"는 매력처럼 작동합니다, 감사합니다. –

관련 문제