【问题标题】:Javascript infinite loop [duplicate]Javascript无限循环[重复]
【发布时间】:2025-12-23 07:10:09
【问题描述】:

这个例子很简单,我试图一个接一个地改变焦点按钮。我无法做的是让整个过程在按钮一结束时重复。

var allButtons = $(":button");
for (i = 0; i < allButtons.length; i++) {
    (function(index) {
        setTimeout(function() { 
            allButtons[index].focus(); 
        }, 1000*index);
    }(i));
}

<input type="button" value="Here" />
<input type="button" value="Here" />
<input type="button" value="Here" />
<input type="button" value="Here" />
<input type="button" value="Here" />
<input type="button" value="Here" />

input[type="button"]:focus { 
    color:red; 
}

See working example

【问题讨论】:

  • 请在您的问题中包含代码,而不仅仅是链接。谢谢。

标签: javascript infinite-loop


【解决方案1】:

只需使用一个setInterval 函数...

var index = -1;

setInterval(function() {
    index = (index + 1) % buttons.length;
    buttons[index].focus();
}, 1000);

【讨论】:

  • 这将遍历所有按钮一次然后在达到buttons.length + 1时失败,不是吗?
  • 关闭,但您在第一次通过此实现时不小心跳过了第一个按钮。确保在设置焦点之后增加index,而不是之前。
  • @RwL:他正在使用 mod 功能来防止这种情况发生 - 将索引保持在按钮的长度内。
  • @Nightfirecat 是的,但是第一个.focus()buttons[1] 上,实际上是buttons[0] 之后的第二个按钮
  • @Andrea Hare:已修复。我更喜欢让index 成为最后一个(即当前)聚焦按钮,以防其他事件需要...(index == -1 表示尚未聚焦任何按钮)。
【解决方案2】:

答案很简单:递归。示例:http://jsfiddle.net/DduJU/

var allButtons = $(":button"),
    index = 0;
(function focus() {
    allButtons[index].focus();

    index++;
    setTimeout(focus, index*100);
    //this will be executed even though we called setTimeout
    //if index is larger than available buttons, restart it
    if (index >= allButtons.length)
        index = 0;
}());

我尽量远离setInterval。在这个例子中,它可能工作得很好,但是setInterval 将每 n 毫秒执行一次,即使该函数可能在那个时间内没有完成。在这种情况下,函数调用将堆叠。 setTimeout 仅在大部分功能完成后才在此处调用,因此即使由于某种原因需要更长的时间,您仍然很清楚。

【讨论】:

  • 您的担心是错误的...setInterval 仅在执行返回到主事件循环时安排调用。