gpt4 book ai didi

javascript - 观察 setTimeout 循环,以便一次只有一个在运行

转载 作者:行者123 更新时间:2023-11-29 16:28:51 25 4
gpt4 key购买 nike

我正在用 jQuery 创建一个内容旋转器。共 5 项。项目 1 淡入,暂停 10 秒,淡出,然后项目 2 淡入。重复。

很简单。使用 setTimeout,我可以调用一组创建循环的函数,并将无限期地重复该过程。

我现在想通过单击导航元素直接跳转到其中一个内容项来添加随时中断此旋转器的功能。

我最初开始沿着不断 ping 变量的路径(比如每半秒)检查导航元素是否被单击,如果是,则放弃循环,然后根据单击的项目重新启动循环被点击了。

我遇到的挑战是如何通过计时器实际 ping 一个变量。解决方案是深入研究 JavaScript 闭包……这有点超出我的理解范围,但绝对是我需要深入研究的内容。

然而,在这个过程中,我想出了一个替代方案,实际上似乎在性能方面更好(至少理论上是这样)。我在这里运行了一个示例:

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);
})

如果我从点击事件中注释掉“startLoop...”,它确实会停止初始循环。但是,如果我保留最后一行,它实际上并没有停止初始循环。为什么?发生的情况是两个循环似乎在一段时间内并行运行。

因此,当我单击我的导航时,会调用 clearTimeout 来清除它。

最佳答案

你应该做的是保存 setTimeout 返回的句柄并用 clearTimeout 清除它以中断旋转器。

var timeout = null;

function doThatThing() {
/* Do that thing. */

// Schedule next call.
timeout = setTimeout(doThatOtherThing, 5000);
}

function doThatOtherThing() {
/* Do that other thing. */

// Schedule next call.
timeout = setTimeout(doThatThing, 5000);
}

function interruptThings() {
if (timeout != null) {
// Never mind, cancel the scheduled task.
clearTimeout(timeout);
timeout = null;
}
}

单击导航元素时,只需调用 interruptThings()。好的部分是它会立即生效,您不需要进行任何轮询或任何其他复杂的操作。

关于javascript - 观察 setTimeout 循环,以便一次只有一个在运行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2739673/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com