2011-04-05 72 views
7

我剛開始看javascript,所以希望這會很簡單。我想製作一個自動播放圖像的幻燈片。這非常簡單,並且有幾個教程,但由於某些原因,我無法使其工作。這是我的:Javascript遞歸settimeout

var image1 = new Image(); 
var image2 = new Image(); 
var image3 = new Image(); 
image1.src = "images/website6.jpg"; 
image2.src = "images/website7.jpg"; 
image3.src = "images/sunset.jpg"; 
var images = new Array(
    "images/website6.jpg", 
    "images/website7.jpg", 
    "images/sunset.jpg" 
); 
setTimeout("delay(images,0)",2000); 
function delay(arr,num){ 
    document.slide.src = arr[num % 3]; 
    var number = num + 1; 
    setTimeout("delay(arr,number)",1000); 
} 

我試圖改變的圖像有id幻燈片。而且我也有一些證據表明它有效。發生的第一個圖像加載。然後加載第二個圖像(這意味着原始setTimeout調用必須工作)。然後沒有任何反應對我而言,這表明這是遞歸不起作用。

我對其他語言的遞歸非常熟悉,所以我認爲它只是一個語法的東西或什麼,但我似乎無法弄清楚。謝謝你的幫助。

+0

取消引用第二個setTimeout中的參數。那將是我的第一個猜測。 – Cronco 2011-04-05 22:55:51

+0

@Cronco有趣的是,如果我這樣做,我不會得到第二個圖像...這表明這是什麼使圖像更改一次。此外,我見過的每個示例都有引號,這就是爲什麼我放入它們的原因。 – Paul 2011-04-05 22:59:37

+0

引用變量的問題在於定時器正在運行完整字符串'「delay(arr,number)」'而不是將變量到它們的存儲值 - 這就是爲什麼不引用它會起作用的原因(儘管你仍然需要像這樣引用它們......'「delay(''+ arr +'',''+ number +'')'。然而,爭議點 - Pointy的回答比較好,我只是在解釋發生了什麼。 – 2011-04-05 23:40:50

回答

15

問題是,當您傳遞字符串以評估「setTimeout」調用時,評估將在全局上下文中完成(稍後,何時該觸發)。因此,你的方式更好(對於很多其他的原因)通過實際的功能:

setTimeout(function() { delay(images, 0); }, 2000); 
function delay(arr, num) { 
    document.slide.src = arr[num % 3]; 
    setTimeout(function() { delay(arr, num + 1); }, 1000); 
} 

更現代的瀏覽器,你可以使用「.bind()」方法的函數來創建一個功能這是預先綁定在用作this東西:

setTimeout(delay.bind({arr: images, num: 0}), 2000); 
function delay() { 
    document.slide.src = this.arr[this.num % 3]; 
    setTimeout(delay.bind({arr: this.arr, num: this.num + 1}), 1000); 
} 

一個六,其他的半打,但只是爲表明有多種方式來做事的例子。

+0

真棒,它現在有效。我仍然有點困惑,爲什麼我的代碼不工作,你說它被評估「稍後,什麼時候該發生,爲什麼它永遠不會到達那個部分?爲什麼使用匿名函數會改變這個呢?如果有一些很好的文檔能夠覆蓋這個,那麼我會很感激鏈接。謝謝。 – Paul 2011-04-05 23:07:33

+0

問題是,字符串「delay(arr,number)」需要能夠獲得變量「arr」a nd「號碼」爲了使它有意義。由於字符串「eval()」的作用方式(現在我想到了,無論它是在setTimeout調用時還是以後都沒關係),它是在與超時函數本身不同的上下文中完成的;這只是語言工作的方式。 – Pointy 2011-04-05 23:45:23

+0

當您使用** real **函數時,函數意義在實際調用「setTimeout()」的範圍內發生的解釋。這個函數**可以訪問局部變量,這也是因爲JavaScript的工作原理。 – Pointy 2011-04-05 23:46:14

1

我會非常懷疑第二個setTimeout電話。我將通過使用顯式函數與字符串表達式來使其更清晰

setTimeout(function() { delay(arr, number); }, 1000);