Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 使用for each和setTimeout无限次迭代数组_Javascript_Arrays_For Loop_Settimeout - Fatal编程技术网

Javascript 使用for each和setTimeout无限次迭代数组

Javascript 使用for each和setTimeout无限次迭代数组,javascript,arrays,for-loop,settimeout,Javascript,Arrays,For Loop,Settimeout,我在myClass中有这个方法。当它到达数组的末尾时,我希望它再次从0开始,但此时它刚好停止 this.jsonParse = function() { for (var i = 0; i < this.numberOfPhotos; i++){ (function(index, selector, timing, arrayLength){ setTimeout(function() { $(selector

我在
myClass
中有这个方法。当它到达数组的末尾时,我希望它再次从0开始,但此时它刚好停止

this.jsonParse = function() {
    for (var i = 0; i < this.numberOfPhotos; i++){
         (function(index, selector, timing, arrayLength){
            setTimeout(function() {
               $(selector).css('background-color': obj_gallery.images[index].hex);
            }, index*timing);            
         })(i, this.slideWrap, this.timing,this.numberOfPhotos);
    }
}

NB
this.numberOfPhotos
等局部变量之前已经定义过。

我想您可能需要使用setInterval()来代替-


我建议使用一种不同的方法,使用递归,而不是增量超时。首先,我将创建一个可重用的抽象:

function cycle(delay, f, xs) {
   var run = function(i) {
      setTimeout(function() {
         f(xs[i])
         i += 1
         if (i >= xs.length) {
            i = 0
         }
         run(i)
      }, delay)
   }
  f(xs[0])
  run(1)
}
然后您可以执行以下操作:

this.jsonParse = function(){
    var $el = $(this.slideWrap)
    var bgcolor = function(img) {
        $el.css('background-color', img.hex)
    }
    cycle(this.timing, bgcolor, obj_gallery.images)     
};

例如:

虽然我想我知道你想做什么(无限期地旋转图像),但你的方法相当可怕。假设旋转中有1000个图像,则至少有1000个计时器在运行,并且一次加载所有1000个图像

相反,我会使用一种简单得多的方法,在索引上使用一个模运算符,并使用一个简单的函数来更新两个图库图像中的一个

首先,基本HTML非常简约:

<div id="gallery">
    <img id="gallery_a" onload="galleryLoaded()" />
    <img id="gallery_b" onload="galleryLoaded()" />
</div>
定期调用的函数(也可以通过按钮或某些链接启动)将更新当前图像的索引并交换当前不可见的图像:

onload
事件将切换图像(基本上只是根据需要隐藏第二个图像):

最后但并非最不重要的一点是,您必须设置间隔并立即显示第一幅图像

// This function will init the switch
function galleryNext() {
    if (gallery_switching)
        return;

    // Prevent multiple switches at once    
    gallery_switching = true;

    // Get the next index (the modulo will make it wrap around)
    gallery_index = (gallery_index + 1) % images.length;

    // Update the inactive image
    // This could also update some link target or similar
    document.getElementById(gallery_second ? 'gallery_a' : 'gallery_b').src = images[gallery_index];

    // Toggle the next image
    gallery_second = !gallery_second;
}

当然,您也可以在其他地方为图像设置初始的
src

您可以创建一个小提琴吗?是的,对不起
.css('background-color':obj_gallery…
。这种语法看起来不正确。这可能是个愚蠢的问题,但是如果(i>arraylelength){i=0;}?@elclars我错过了背景色值的引号(对吗?),但它完成了…看这支笔。我的问题在cicle上。这个答案没有反映出良好的编码实践,我试图尽可能详细地说明:)抱歉@buzzy,为什么你的答案没有反映出良好的编码实践??谢谢1)您应该缓存选择器。2) 您可能可以使用比index==numberOfPhotos更简单的检查。3) 您可能希望保存setInterval的返回值以停止它。我写这篇文章只是为了举例说明setInterval如何解决您的问题。@Buzzy:只需使用modulo:
index=(index+1)%numberOfPhotos
。另外,如果您想在图像上使用可变时间,只需在
galleryLoaded()
中使用
setTimeout()
,而不是使用固定时间间隔回调。
<div id="gallery">
    <img id="gallery_a" onload="galleryLoaded()" />
    <img id="gallery_b" onload="galleryLoaded()" />
</div>
#gallery_b {
    opacity: 0;
    transition: opacity 1s;
}
// This function will init the switch
function galleryNext() {
    if (gallery_switching)
        return;

    // Prevent multiple switches at once    
    gallery_switching = true;

    // Get the next index (the modulo will make it wrap around)
    gallery_index = (gallery_index + 1) % images.length;

    // Update the inactive image
    // This could also update some link target or similar
    document.getElementById(gallery_second ? 'gallery_a' : 'gallery_b').src = images[gallery_index];

    // Toggle the next image
    gallery_second = !gallery_second;
}
// This function is a callback once the next image has been loaded
function galleryLoaded() {
    if (!gallery_switching)
        return;
    gallery_switching = false;

    // If the second image is the next, we'll have to hide it now (since we want to show the first one)
    document.getElementById('gallery_b').style.opacity = gallery_second ? 1 : 0;
}
setTimeout(galleryNext, 0); // Fake "onload" here
setInterval(galleryNext, 2500); // Switch once every 5 seconds