2011-04-05 85 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);