2009-12-18 4 views
1

내가 문제 자체가 겉보기에, 나는 ... 누군가가 이의 이유에 도움이 되거 수 바라고 있어요 해결 가지고 있지만의 jQuery .remove() 콜백의 호출은 무한 루프를 유발

다음은 두 개의 스냅 샷은 사용자 피드백 메시지가 포함 된 div를 제거하는 것이 동일한 기능입니다. 선택적인 타임 아웃을 사용하기위한 설정입니다. 타임 아웃이 지정되면 setTimeout()을 사용하여 자신을 호출하여 div를 제거합니다. 문제 버전 I은 this.remove를 (전화 먼저 blackbirdjs 등을 이용하여 로그 메시지를 전송) - - 후

함수의 두 버전 사이의 차이점은 여기서 this.remove() 호출된다 이것은 브라우저가 그들을 펌핑 할 수있는만큼 빠른 "제거 피드백 div ..."의 끝내지 않는 로그 메시지로 넘치게됩니다.

그러나 작업 버전에서는 순서를 반대로하고 모든 것이 정상적으로 실행되고 모두가 잘 ...

나는이 사건의 순서가 사소하지만 분명히 아니라고 생각할 것이다. 누가 이런 일이 일어날 지에 대해 좀 더 밝힐 수 있습니까? 이 jQuery 버그 또는 블랙 버드 또는 자바 스크립트의 이상한 버킷 일반적으로 문제가 있습니까?

참고 : - 그것은 내가 돌아 그에게이 그것을 중지 다시 거짓 온 경우 -
내가) (확인 전화를 사용하여 일부 혼합 성공을 거두었 그러나, 제거 호출 후 바로 추가 수익은 영향을 미치지 않았다 .

흥미롭게도, 어느 버전이 IE8에서 제대로 작동하는 것 같습니다. - 이것이 파이어 폭스/도마뱀 문제 일 수 있습니까?

문제 코드 :

function clear_feedback(target_container, timeout){ 
    log.debug("timeout: " + timeout); 
    log.debug("target_container: " + target_container); 

    if(timeout == undefined){ 
     log.info("removing target..."); 

     $(target_container).children(".update_feedback").slideUp("slow", 
      function() { 
       log.info("Removing feedback div..."); 
       this.remove(); 
      } 
     ); 
    } 
    else{ 
     log.info("Setting timeout, THEN removing target..."); 

     setTimeout("clear_feedback('" + target_container + "')", timeout); 
    } 
} 

작업 코드 : 난 그냥 같이하지만 다른 맥락에서 문제를 보았다

function clear_feedback(target_container, timeout){ 
    log.debug("timeout: " + timeout); 
    log.debug("target_container: " + target_container); 

    if(timeout == undefined){ 
     log.info("removing target..."); 

     $(target_container).children(".update_feedback").slideUp("slow", 
      function() { 
       this.remove(); 
       log.info("Removing feedback div..."); 
      } 
     ); 
    } 
    else{ 
     log.info("Setting timeout, THEN removing target..."); 

     setTimeout("clear_feedback('" + target_container + "')", timeout); 
    } 
} 

답변

1

blackbirdjs 콘솔에 의존하는 대신 브라우저 오류 콘솔을 확인해야합니다.

는 그런 다음 브라우저 오류 콘솔 (코드 버전 중 하나를 사용하여)도 오류 메시지와 함께 침수 것을 눈치 챘을 것이다

코드의 실제 문제는

this.remove(); 

this는 HTML입니다 DOM 요소를 호출하고 함수 remove()을 가지지 않으므로 자식은 숨겨 지지만 실제로 삭제되지는 않습니다. this.remove()에 예외가 있습니다. 콜백 함수가 예외를 throw 할 때 jQuery는 무한 루프로 끝나기 때문에 끝납니다.

jQuery 객체에서 요소를 래핑하면됩니다. 두 번째 버전은 오류

log.info("Removing feedback div..."); //error logged 
this.remove(); //exception 

this.remove(); //exception 
//log line not executed as previous line threw exception 
log.info("Removing feedback div..."); 

jQuery를도와 무한 루프 이것이 맞다면 끝난다는 사실을 고정 된 것으로 보인다 이유

$(this).remove(); 

는 지금은 분명 행동은 논쟁의 여지가 있기 때문에 jQuery의 내부 동작에 대한 더 깊은 조사가 필요합니다. 하지만이 realted 버그 티켓이되지 않은 관심을 주셔서

에 관심있는

http://dev.jquery.com/ticket/2846

+0

gah ..../head-slam-on-desk 나는 아직 이것을 시험 할 기회가 없었고 아마도 다음 (크리스마스 휴가가 연말 연시에 금요일에 시작되었다.) 휴가를 가지지 않을 것이다. 이 오류를 읽은 후에 오류가 꽤 분명해 보입니다 ... 신인의 실수입니다. –

+0

오래 지연되어서 죄송합니다. 첫날 직장에 복귀합니다. 많은 감사합니다! –

0

; 그러나 근본 원인이 같다고 생각합니다.

log.info를 보면 DOM에 노드가 삽입 된 것을 볼 수 있습니다. jquery 함수 중 하나가 log.info가 노드를 삽입하는 바로 그 지점에서 올바른 위치에서 DOM을 탐색 한 다음 콜백이 호출되면 해당 콜백이 다른 노드를 삽입합니다 노드로 이동하면 무한 루프가됩니다.

이것이 IE8에서 발생하지 않는 이유는 DOM 구조가 브라우저간에 정확히 동일하지 않거나 IE8이 DOM 노드 삽입을 처리하는 데있어 다른 전략을 사용하는 것과 같은 두 가지 이유 중 하나 일 수 있습니다. 코드가 트리를 가로 지르고 있습니다.

방화 광을 사용하여 문제가있는 줄 주위에 중단 점을 배치 한 다음 DOM 트리를보고 이와 같은 동작을 감지 할 수 있는지 알아보십시오.

+0

쿨 - 정보 주셔서 감사합니다 - 나는 조사하고 알려 드리겠습니다 무엇을, 어떤 경우, I 발견. –

관련 문제