【发布时间】:2010-04-29 18:10:46
【问题描述】:
我正在 jQuery 中创建一个内容旋转器。共 5 项。第 1 项淡入,暂停 10 秒,然后淡出,然后第 2 项淡入。重复。
足够简单。使用 setTimeout,我可以调用一组函数来创建循环并无限期地重复该过程。
我现在想通过单击导航元素直接跳转到其中一个内容项来添加随时中断此旋转器的功能。
我最初开始沿着不断 ping 变量的路径(比如每半秒)检查是否单击了导航元素,如果是,则放弃循环,然后根据该项目重新启动循环被点击了。
我遇到的挑战是如何通过计时器实际 ping 变量。解决方案是深入研究 JavaScript 闭包……这有点超出我的想象,但绝对是我需要深入研究的东西。
但是,在此过程中,我想出了一个替代选项,实际上似乎在性能方面更好(至少在理论上)。我在这里运行了一个示例:
(它使用console.log,所以运行fireBug)
示例脚本:
$(document).ready(function(){
var loopCount = 0;
$('p#hello').click(function(){
loopCount++;
doThatThing(loopCount);
})
function doThatOtherThing(currentLoopCount) {
console.log('doThatOtherThing-'+currentLoopCount);
if(currentLoopCount==loopCount){
setTimeout(function(){doThatThing(currentLoopCount)},5000)
}
}
function doThatThing(currentLoopCount) {
console.log('doThatThing-'+currentLoopCount);
if(currentLoopCount==loopCount){
setTimeout(function(){doThatOtherThing(currentLoopCount)},5000);
}
}
})
触发元素的每次点击都会启动循环,将一个等于全局变量当前值的变量传递给自身。该变量在循环中的函数之间来回传递。
触发器的每一次点击也会增加全局变量,以便循环的后续调用具有唯一的局部变量。
然后,在循环中,在调用每个循环的下一步之前,它会检查它所拥有的变量是否仍然与全局变量匹配。如果没有,它知道一个新的循环已经被激活,所以它只是结束现有的循环。
对此有什么想法?有效的解决方案?更好的选择?注意事项?危险?
更新:
我在下面通过 clearTimeout 选项使用 John 的建议。
但是,我不能让它工作。逻辑是这样的:
var slideNumber = 0;
var timeout = null;
function startLoop(slideNumber) {
//... code is here to do stuff here to set up the slide based on slideNumber...
slideFadeIn()
}
function continueCheck() {
if (timeout != null) {
// cancel the scheduled task.
clearTimeout(timeout);
timeout = null;
return false;
} else {
return true;
}
};
function slideFadeIn() {
if (continueCheck){
// a new loop hasn't been called yet so proceed...
$mySlide.fadeIn(fade, function() {
timeout = setTimeout(slideFadeOut,display);
});
}
};
function slideFadeOut() {
if (continueCheck){
// a new loop hasn't been called yet so proceed...
slideNumber=slideNumber+1;
$mySlide.fadeOut(fade, function() {
//... code is here to check if I'm on the last slide and reset to #1...
timeout = setTimeout(function(){startLoop(slideNumber)},100);
});
}
};
startLoop(slideNumber);
上述循环的踢脚。
然后我有导航项,当单击时,我希望上述循环停止,然后以新的开始幻灯片重新开始:
$(myNav).click(function(){
clearTimeout(timeout);
timeout = null;
startLoop(thisItem);
})
如果我从 click 事件中注释掉“startLoop...”,它确实会停止初始循环。但是,如果我留下最后一行,它实际上并没有停止初始循环。为什么?发生的情况是两个循环似乎并行运行了一段时间。
因此,当我单击导航时,将调用 clearTimeout 来清除它。
【问题讨论】:
标签: javascript loops