2009-12-18 69 views
1

雖然我本身的問題看似解決了,我希望有人能擺脫對的這究竟是爲什麼一些輕...jQuery的一個.remove()回調調用觸發無限循環

下面是兩個快照其作用是刪除包含用戶反饋消息的div。它設置爲使用可選的超時,如果指定了超時,它使用setTimeout()調用自己,然後移除div。

函數的兩個版本之間的唯一區別就是this.remove()被稱爲 - 在這個問題的版本我使用blackbirdjs,然後再調用this.remove(發送消息到日誌) - 後這會執行日誌充斥着無數日誌消息「Removing feedback div ...」,就像瀏覽器可以將它們吸入一樣快。

但是,在工作版本中,我只是顛倒了順序,一切正常執行,一切都很好...

我很難過,我會認爲在這種情況下的順序是微不足道的,但顯然不是。任何人都可以闡明爲什麼會發生這種情況?這是一個jQuery錯誤還是黑鳥的問題或一般的JavaScript的怪異怪異?

注:
我只好用電話確認()一些混雜的成功 - 如果它回來了假,我告訴它返回,該停止了它 - 但是,刪除呼叫後,只是增加收益無影響。

有趣的是,兩個版本似乎都能在IE8中正常工作 - 所以這可能是firefox/gecko問題?

問題代碼:

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()你會得到一個例外。由於回調函數拋出一個異常,jQuery以無盡的循環結束,試圖完成它的工作

你需要做的是將元素包裝在一個jQuery對象中。

$(this).remove(); 

現在也不清楚爲什麼第二個版本似乎已經解決了這一錯誤

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的,即使在和無限循環,如果這是正確結束的事實行爲是有爭議的,需要深入研究jQuery的內部工作。但是,這是不感興趣的,你

對於那些有興趣有realted的bug票

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

+0

gah ..../head-slam-on-desk我還沒有機會測試這一點,並可能不會在下一段時間(週五聖誕節假期開始時帶了一些年假),但看完這個錯誤似乎很清楚......菜鳥的錯誤。 – 2009-12-20 04:10:06

+0

對不起,很長的延遲 - 第一天回到工作。非常感謝! – 2010-01-04 14:13:04

0

我所看到的一個問題就是這樣的,但在不同的上下文;不過,我懷疑根本原因是一樣的。

如果你看看log.info,你會發現它會在DOM中插入一個節點。如果其中一個jquery函數碰巧正好在正確的位置遍歷DOM,特別是在log.info插入節點的地方,然後如果這導致您的回調被調用,那麼您的回調會插入另一個節點,並最終陷入無限循環。

爲什麼在IE8中不會發生這個問題很可能是兩個原因之一:或者DOM結構在瀏覽器中不完全相同,或者IE8使用不同的策略來處理DOM節點插入,而javascript代碼遍歷樹。

您可能會嘗試使用Firebug,在有問題的行周圍放置斷點,然後查看DOM樹以查看是否可以發現類似這樣的行爲。

+0

酷 - 感謝您的信息 - 我會進行調查並讓你知道什麼,如果有的話,我找。 – 2009-12-19 15:11:34