我正在jQuery中创建一个内容旋转器。共5项。项目1淡入,暂停10秒,淡出,然后项目2淡入。重复。
现在我想添加一种能力,通过单击导航元素直接跳转到一个内容项,随时中断这个旋转器。
我最初开始沿着不断ping一个变量(比如每半秒一次)的路径走下去,检查是否单击了导航元素,如果是,则放弃循环,然后根据单击的项重新启动循环。
然而,在这个过程中,我提出了一个替代选择,实际上似乎是更好的性能明智(理论上,至少)。我这里有一个样本:
http://jsbin.com/uxupi/14
(它正在使用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事件中注释掉“startoop…”,它确实会停止初始循环。但是,如果我把最后一行放进去,它实际上不会停止初始循环。为什么?结果是两个循环似乎并行运行了一段时间。
所以,当我点击我的导航时,clearTimeout被调用,它会清除它。