2012-01-05 131 views
1

我試圖做一個幻燈片使用jquery,圖片循環的函數,每5.5秒調用一次函數。但是,我試圖避免遞歸,因爲它與迭代調用相比非常昂貴。我假設這是IE瀏覽器加載幻燈片時有非停止加載圖標的原因。所以我想將下面的函數轉換爲迭代函數。如何將遞歸函數轉換爲循環函數與jquery/javascript

function playslides() 
{ 

//hide previous slide 
$(document.getElementById(t)).fadeOut("slow"); 


//reset slide index 
calcSildes(); 

//show new slide 
$(document.getElementById(t)).fadeIn("slow"); 

//recursive call after 5.5 sec 
timer = setTimeout("playslides()", 5500); 

} 


//on page load... 

$(document).ready(

playslides(); 

); 

到目前爲止,我的兩個方法是:

  1. 創建$(文件)。就緒()函數和循環playslides()函數中while循環。

  2. 創建另一個調用playslides()函數的計時器函數,並讓playslides函數調用該計時器函數。 (不知道這是否可以避免遞歸......)

謝謝!!

+1

爲什麼不使用jQuery幻燈片放映插件之一? – jrummell 2012-01-05 18:46:32

+0

你爲什麼認爲這是非常昂貴的?您重複的DOM選擇將是應該修復的最昂貴的事情。 – 2012-01-05 19:11:13

+0

感謝所有,我更改函數使用SetInterval而不是SetTimeout後,頁面加載後IE的旋轉加載圖標仍然存在,任何想法可能會導致這種情況?難道是「重複的DOM選擇」?謝謝! – eastboundr 2012-01-05 21:10:35

回答

5

聽起來像是你應該setInterval()取代setTimeout(),這將簡單地重複給定函數,直到其取消。不需要遞歸或循環。

Quoting John Resig,創作者的jQuery:

從根本上說重要的是要了解的JavaScript 定時器工作。很多時候,它們的行爲並不直觀,因爲它們所在的單線程是 。讓我們從檢查我們訪問的三個函數開始,它們可以構造和操作定時器。

var id = setTimeout(fn, delay); - 啓動一個定時器,它會在延遲後調用指定的函數。該函數返回一個 唯一的ID,用它可以在稍後取消定時器。

var id = setInterval(fn, delay); - 與setTimeout類似,但不斷調用該函數(每次都有延遲),直到它被取消。

clearInterval(id);clearTimeout(id); - 接受一個計時器ID(通過前述的函數返回 )和發生停止定時器 回調。

使用setInterval,可以簡化您的代碼如下:

function playslides() 
{ 
    //hide previous slide 
    $(document.getElementById(t)).fadeOut("slow"); 

    //reset slide index 
    calcSildes(); 

    //show new slide 
    $(document.getElementById(t)).fadeIn("slow"); 
} 

$(document).ready(function() { 
    setInterval(playslides, 5500); 
}); 
+2

這是值得通過bobince閱讀這篇文章的答案:http://stackoverflow.com/questions/729921/settimeout-or-setinterval-關於什麼時候使用'setTimeout'和何時使用' setInterval'。 – 2012-01-05 19:24:27

+0

感謝jrummell,但是當我改變函數使用SetInterval而不是SetTimeout後,頁面加載後IE的旋轉加載圖標仍然存在,有什麼想法可能導致這種情況?謝謝! – eastboundr 2012-01-05 21:11:26

+0

這通常意味着資源(圖像,腳本等)仍在加載。我沒有看到任何會導致這種情況的代碼示例。 – jrummell 2012-01-05 21:19:57

1

您無法創建具有延遲迭代的循環。

唯一的優化與playslides更換"playslides()",並緩存它指的是同一個對象jQuery的對象:

var timer; 
function playslides($element) { 
    //hide previous slide 
    $element.fadeOut("slow"); 

    //reset slide index 
    calcSildes(); 

    //show new slide 
    $element.fadeIn("slow"); 

    //recursive call after 5.5 sec 
    timer = setTimeout(playslides, 5500, $element); 
} 

// Bug fix too, wrap document.ready in `function(){ 
$(document).ready(function(){ 
    playslides($("#"+t));  
}); 
1

這不是一個遞歸函數。遞歸函數繼續在內存中創建並保留其自身的副本,直到達到基本情況,之後,堆棧展開並返回值。遞歸調用中的參數也必須改變,這最終會導致基本情況。

PHP實例:

function recursive_function($num){ 
    if ($num == 0){ //base case 
     return 10; 
    }else{ 
     return $num + recursive_function($num-1); 
    } 
} 

recursive_function(5);//output is 25 

你的功能僅僅是創造新的計數器,調用同一個函數原來已經離開了內存後。

刪除'timer = setTimeout(playslides,5500,$ element);'在playslides函數中。

替換'playslides($(「#」+ t));'調用與功能的document.ready:

timer = window.setInterval(function(){ 
    playslides($("#"+t)); 
}, 5500); 

您需要創建的setInterval一個匿名函數正確地傳遞參數(舊版本瀏覽器...不是HTML5)。