【问题标题】:Iterate an array infinite times with for each and setTimeout使用 for each 和 setTimeout 无限次迭代数组
【发布时间】:2015-06-02 07:56:27
【问题描述】:

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

我在下面尝试过类似的方法,但它不起作用。

if (index >= arrayLength) {
    index = 0;
}

注意之前已经定义了this.numberOfPhotos等局部变量。

【问题讨论】:

  • 你能做一个小提琴吗?
  • .css('background-color': obj_gallery...。该语法看起来不正确。
  • 可能是个愚蠢的问题,但你试过if (i &gt; arrayLength) { i = 0; }吗?
  • @elclanrs 我错过了关于背景颜色值的引号(对吗?),但它已经完成了......看看笔。我的问题在 cicle 上。

标签: javascript arrays for-loop settimeout


【解决方案1】:

虽然我想我理解你想要做什么(无限期地旋转图像),但你的方法相当糟糕。假设您有 1000 张图片在轮换中,您将至少运行 1000 个计时器,并且您将一次加载所有 1000 张图片。

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

首先,基本的 HTML 非常简约:

<div id="gallery">
    <img id="gallery_a" onload="galleryLoaded()" />
    <img id="gallery_b" onload="galleryLoaded()" />
</div>

onload 事件用于在加载后实际切换可见图像,并防止在加载完成之前切换图像。

我设置了an example on JSFiddle 来展示这种方法。

这不需要特殊的 CSS。要使过渡效果发挥作用,您需要对第二张图像进行一些最低限度的设置:

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

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

// 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

当然,您也可以在其他位置设置图片的初始 src

【讨论】:

  • 补充说明,如果您想在图像上设置可变时间,您可以简单地在galleryLoaded() 中使用setTimeout(),而不是固定间隔回调。
【解决方案2】:

我认为您可能想改用 setInterval() - http://codepen.io/anon/pen/ogVodo

 this.jsonParse = function(){
  // Ho bisogno di una funziona anonimica per passare i parametri, poiche il setTimeout non lo fa.
  var slideWrap = this.slideWrap;
  var timing = this.timing;
  var numberOfPhotos = this.numberOfPhotos;
  var index =0;
  setInterval(function() {
     $(".gallery").css('background-color', obj_gallery.images[index].hex);
     index++;
     if (index === numberOfPhotos){
        index = 0;
     }
        },timing);            
  };

【讨论】:

  • 这个答案并不反映良好的编码习惯,我试图让它尽可能详细:)
  • 对不起@buzzy,为什么你的回答没有反映好的编码习惯?谢谢
  • 1) 你应该缓存选择器。 2)您可能可以进行比索引 === numberOfPhotos 更简单的检查。 3) 您可能希望保存该 setInterval 的返回值以停止它。我只是将它作为 setInterval 如何解决您的问题的示例。
  • @Buzzy:只需使用模数:index = (index + 1) % numberOfPhotos
【解决方案3】:

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

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

例如:DEMO

【讨论】:

    猜你喜欢
    • 2019-01-12
    • 2015-06-19
    • 1970-01-01
    • 2015-05-21
    • 2017-03-30
    • 1970-01-01
    • 1970-01-01
    • 2011-12-02
    • 1970-01-01
    相关资源
    最近更新 更多