2010-04-26 110 views
2

使用jQuery,我已经构建了一个图像/幻灯片旋转器。在基本设置(在伪代码):停止执行递归JavaScript函数

function setupUpSlide(SlideToStartWith){ 
    var thisSlide = SlideToStartWith; 
    ...set things up... 
    fadeInSlide(thisSlide) 
} 

function fadeInSlide(thisSlide){ 
    ...fade in this slide... 
    fadeOutSlide(thisSlide) 
} 


function fadeOutSlide(thisSlide){ 
    ...fade out this slide... 
    thisSlide.fadeOut(fade, function() { 
    var timeout2 = setTimeout(setupUpSlide(nextSlide),100); 
    } 

我所说的第一个功能,并通过在特定的幻灯片索引,然后它的功能,它的事调用链,然后又再次调用第一功能传入下一个索引。然后这会无限重复(当它到达最后一个项目时重置索引)。

这工作得很好。

我现在想要做的是让某人能够通过点击某个特定的幻灯片号码来替代幻灯片。因此,如果幻灯片#8显示,并且我单击#3,我希望递归停止,然后调用传递到幻灯片#3中的初始函数,然后再次启动该过程。

但我不知道该怎么做。如何恰当地“打破”递归脚本。我是否应该创建某种全局的'watch'变量,如果在任何时候'true'都会返回:false并允许执行新的函数?

更新:增加了更详细的代码显示setTimeout调用

回答

7

使用递归实现幻灯片可能不是一个好主意,因为它最终会给出一个stack overflow

改为使用timeouts

的setTimeout() - 执行代码,在未来

clearTimeout()一段时间 - 取消的setTimeout()

或者intervals

(感谢莉吉特指出了这一点!)

setInterval()方法以指定的时间间隔(以毫秒为单位)调用函数或计算表达式。

setInterval()方法将继续调用该函数,直到调用clearInterval(),或者窗口关闭。

+0

但是,在某些时候,我不需要递归来继续循环吗?也就是说,如果我有6张幻灯片,我需要从1到6,然后重复。使用上述超时方法,如何合并for循环逻辑来增加呼叫? – 2010-04-26 20:30:31

+0

@DA:使用超时可以创建一个无限循环而不会发生堆栈溢出。每个呼叫代表您的循环中的一个步骤。 – 2010-04-26 20:39:51

+0

ack。应该看看我已经接近。原来我们在最后一个函数中使用setTimeout函数(然后调用第一个函数)。我已更新原始帖子中的示例代码。所有这些都是为了避免堆栈溢出问题吗? – 2010-04-26 20:56:31

0

,而不是间接递归,请尝试使用经常性的超时(var timer_id = setInterval(...)),并使用clearTimeout当你想停止它

+0

initTimeout?你的意思是setInterval? (和相应的clearInterval) – Ricket 2010-04-26 20:07:45

+0

是的,我的错误 – matei 2010-04-26 20:09:02

0

这里有一个简单的方法来做到这一点。首先,不是直接调用函数,而是在每个函数的末尾使用window.setTimeout(function(){...}),用最后一行代替...(进行递归调用)。这将防止堆栈溢出。

其次,提供一种与循环进行通信的方式。你的布尔表变量是个好主意。它不一定是全局的,只是与你的点击处理程序链接的功能和幻灯片功能都可以访问 - 例如静态类变量。观察变量的变化并打破循环;或者,让变量成为当前设置的幻灯片。

容易,这并不意味着这是最好的方式来做到这一点。首先,你的JQuery动画调用是异步的,你需要使用它们的回调函数,而不是你在这里做的方式,或者所有的动画都会立刻发生。在一个函数中,您可以在单个函数调用的空间中完成所有这些操作。 JQuery允许您的动画链接链接,并且它还允许您向任何现有的动画发出stop命令。我会首先考虑这种做法,而不是继续现在的设置。