JavaScript的setTimeout
函数可以与闭包内的函数一起使用吗?如果对setTimeout
的调用是在同一个闭包内进行的,该怎么办?
有了我的尝试,看来你做不到。不过,我不确定我是否遗漏了任何东西。
基本上,我想这样做:
var ButtonCycler = (function() {
var ButtonCycler = {};
var autoCycle;
var idx = 0;
var buttonIds = [];
buttonIds[0] = "id1";
buttonIds[1] = "id2";
//"Public" methods
ButtonCycler.startAutoCycle = function() {
autoCycle = true;
cycleButtons();
}
ButtonCycler.stopAutoCycle = function() {
autoCycle = false;
}
//Worker function (effectively private because it's in the closure)
function cycleButtons() {
var radioButton;
if(autoCycle) {
radioButton = document.getElementById(buttonIds[idx]);
radioButton.checked = true;
idx++;
if(idx >= buttonIds.length) {
idx = 0; //Start over at first button
}
setTimeout('cycleButtons()',2500); //Delay for 2.5 seconds
}
}
return ButtonCycler;
})(); //IIFE
然后在onload
页面中,我可以这样做:
ButtonCycler.startAutoCycle();
当用户手动点击其中一个单选按钮时,我可以这样做:
ButtonCycler.stopAutoCycle();
执行循环的机制可以很好地封装在闭包中。
当我尝试这个时,我收到cycleButtons
不存在的错误。但是,对cycleButtons
的初始调用成功了。这是由setTimeout
调用启动的调用失败。
答案 0 :(得分:5)
您将cycleButtons()
作为字符串传递,稍后将使用eval
调用该字符串。这将假设cycleButtons
在全局范围内可用(它不是)。相反,将引用传递给实际函数:
setTimeout(cycleButtons, 2500);
答案 1 :(得分:0)
你的setTimeout不正确,你应该使用clearTimeout来简化你的代码。以下是如何简化它的示例:
var ButtonCycler = (function () {
var ButtonCycler = {};
var autoCycle;
var idx = 0;
var buttonIds = [];
var timer;
buttonIds[0] = "id1";
buttonIds[1] = "id2";
//"Public" methods
ButtonCycler.startAutoCycle = function () {
cycleButtons();
}
ButtonCycler.stopAutoCycle = function () {
clearTimeout(timer);
}
//Worker function (effectively private because it's in the closure)
function cycleButtons() {
var radioButton;
radioButton = document.getElementById(buttonIds[idx]);
radioButton.checked = true;
idx = (idx < buttonIds.length - 1) ? idx + 1 : 0;
timer = setTimeout(function () {
cycleButtons();
}, 2500); //Delay for 2.5 seconds
}
return ButtonCycler;
})(); //IIFE