簡體   English   中英

一個for循環內的SetTimeout

[英]SetTimeout inside a for loop

我正在嘗試編寫一個可更改3張圖像的z-index的腳本。 基本上,腳本應以當前圖片為目標,並在下一張圖片上應用更高的Z索引,就像輪播一樣,但具有Z索引而不是活動類。 挑戰在於在特定間隔后設置z-index。 問題在於顯示的是第一個圖像,然后是最后一個。 這是我的代碼:

HTML:

<div class="changingimages">
    <img src="#" data-time="3000" width="100%" class="alternateimage alternateimage1">
    <img src="#" data-time="2000" width="100%" class="alternateimage alternateimage2">
    <img src="#" data-time="4000" width="100%" class="alternateimage alternateimage3">
</div>

jQuery腳本

<script type="text/javascript">

jQuery(document).ready(function(){

    var changeImg = function(i, time, currentImg) {

        setTimeout(function(){

            jQuery(currentImg).next().css("z-index", i);

        }, time);
    };

    var numberOfChilds = jQuery(".changingimages").children().length;
    var currentIndexClass;
    var currentImg;
    var time;

    for (var i=1; i<=numberOfChilds; i++) {

            currentIndexClass = '.alternateimage' + i;
            currentImg = jQuery(currentIndexClass);
            time = jQuery(currentIndexClass).attr("data-time");

            changeImg(i, time, currentImg);

    }

});

我認為循環中的閉包存在一些問題,但不確定!

常見的誤解是setTimeout將事件安排為相對於先前排隊的事件運行。 從理論上講,您似乎相信以下內容:

setTimeout(f, 100);
setTimeout(g, 100);
setTimeout(h, 100);

會導致這樣的時間軸:

0ms   Start
100ms Run f()
200ms Run g()
300ms Run h()

現實情況是setTimeout中的time選項表示“至少在經過這么多時間后運行此函數”。 從上一個示例來看,您實際上會得到更多類似的信息

0ms   Start
100ms Run f()
101ms Run g()
102ms Run h()

為了正確地分隔代碼,請繼續增加超時時間,而不是替換超時時間。

var time = 0;

for (var i = 1; i <= numberOfChilds; i++) {
  currentIndexClass = '.alternateimage' + i;
  currentImg = jQuery(currentIndexClass);

  // Add to the previous time
  time += parseInt(jQuery(currentIndexClass).attr("data-time"), 10);
  changeImg(i, time, currentImg);
}

這是一個小工具,實現了使用超時來實現所需的功能。

小提琴

.textArea {
  position: absolute;
  height: 50px;
  width: 50px;
  display: block;
}

.box_a {
  background-color: blue;
}

.box_b {
  background-color: red;
}

.box_c {
  background-color: orange;
}

.active {
  z-index: 3;
}


<div class="textArea box_a active">a</div>
<div class="textArea box_b">b</div>
<div class="textArea box_c">c</div>

$(function(){
  var $elem = $('.textArea');

  timeout(0);

  function timeout(i){
    $($elem[i]).addClass('active');
    return setTimeout(function(){
      $elem.removeClass('active');
      i++;
      if(i >= $elem.length){
        i = 0
      }
      timeout(i);
    }, 1000)
  }
});

請注意,它不使用for循環,因為超時是異步的,不會順序執行。 基本上每個超時都會在同一時間觸發,然后根據等待時間執行其操作。

解決方案是創建一個跟蹤索引以及上次超時何時完成執行的函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM