jQuery:如何通过each()函数实现数组的无限循环?

4
这里是jsFiddle链接: http://jsfiddle.net/F6nJu/ 我有一个带颜色的盒子:
<div id="colorblock"></div>
#colorblock { background:#3ff; width: 100%; height: 300px; }

我有一个在JavaScript中创建的颜色数组:

var arr = [ "#f00", "#ff0", "#f0f", "#f66"];

我使用jQuery的each()函数遍历这些颜色:
$.each(arr, function(key, value) {
  $('#colorblock').delay('1200').animate({backgroundColor:value}, 600);
});

当数组迭代到末尾时,如何重新开始数组迭代(使动画无限循环)?

为什么要迭代,当你可以直接使用数组索引呢?i=0; arr[i++ % arr.length] - neurino
4个回答

11
var arr = ["#f00", "#ff0", "#f0f", "#f66"];

// run through the array forever
(function recurse(counter) {
    // get the colour
    var color = arr[counter];
    // animate it
    $('#colorblock').delay('1200').animate({
        backgroundColor: color
    }, 600);
    // delete the value to save memory
    delete arr[counter];
    // add the value at the end of the array
    arr.push(color);
    // run it again for the next number
    setTimeout(function() {
        recurse(counter + 1);
    }, 200);
// start it for the first number.
})(0);

无限递归。删除当前条目,然后将当前值添加到末尾。

实时示例

对于那些对数组长什么样子感兴趣的人:

["#foo", "#ff0", "#f0f", "#f66"] (counter = 0)
[undefined, "#ff0", "#f0f", "#f66", "#foo"] (counter = 1)
[undefined, undefined, "#f0f", "#f66", "#foo", "#ff0"] (counter = 2)
[undefined, undefined, undefined, "#f66", "#foo", "#ff0", "#f0f"] (counter = 3)
[undefined, undefined, undefined, undefined, "#foo", "#ff0", "#f0f", "#f66"] (counter = 4)
etc.

我假设你正在使用我的 set_color 函数? - Naftali
你的代码最后一行是:})(0); 我试着改变了数字:0、1、2、3。有趣的事情发生了。这到底是什么? - Roko C. Buljan
1
@roXon 添加了更多的细节/注释。 - Raynos
@Raynos... 你真好!你刚刚赚得了+10分!(我只是找不到按钮;)好吧...+1 - Roko C. Buljan
完美的解决方案...但如何切换它?我正在尝试使用jQuery .toggle(),并在recurse()上停止()。 - Riccardo Volpe

5

试试这个:

var arr = ["#f00", "#ff0", "#f0f", "#f66"];
$.each(arr, function(key, value) {
    set_color(value);
});

function set_color(color) {
    $('#colorblock').delay('1200').animate({
        backgroundColor: color
    }, 600);
    setTimeout(function() {
        set_color(color);
    }, 2000); //restart in 2 seconds
}

Fiddle: http://jsfiddle.net/maniator/F6nJu/1/


1
这个可以用,谢谢!setTimeout()函数似乎不起作用,但没关系,因为我在动画之前设置了延迟。 - superUntitled
@Neal...如果已经设置了延迟,为什么还需要setTimeout?如果我移除timeout,动画就会停止。setTimeout实际上是做什么的?提前感谢! - Roko C. Buljan
@superUntitled,那个颜色只需要2秒钟,不是任何颜色。 - Naftali
@roXon setTimeout 正在递归调用该函数。 - Naftali
$.each用于不是jQuery元素的数组? 呸。 使用for或while循环。 - user1385191
@Matt!哇哇哇哇,请停一下! 这变得很有趣了!你能稍微改变一下这个小段代码吗?用for循环或while循环会是什么样子呢?(非常感谢!) - Roko C. Buljan

2
Array.prototype.recurse = function(callback, delay) {
   delay = delay || 200; 
   var self = this, idx = 0;

   setInterval(function() {
      callback(self[idx], idx);
      idx = (idx+1 < self.length) ? idx+1 : 0;
   }, delay);
}

在StackOverFlow上尝试一下:

["#f00", "#ff0", "#f0f", "#f66"].recurse(function(item, index) { 
    $('body').css('background-color', item);
}, 300);

0
var arr = ["#f00", "#ff0", "#f0f", "#f66"];

(function recurse(counter) {
    var arrLength = arr.length;
    var index = counter%arrLength;

    var color = arr[index];

    $('#colorblock').delay('1200').animate({
       backgroundColor: color
     }, 600);

    setTimeout(function() {
       recurse(counter + 1);
    }, 200);

})(0);

1
在问题被提出并被接受5年后发布,我建议您添加一些详细信息,说明为什么这个解决方案更好。 - Gilad Green

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接