javascript - get SetTimeout to finish before continuing loop - Stack Overflow

I'm trying to get a row of letters to light up one by one using Javascriptjquery.I created an a

I'm trying to get a row of letters to light up one by one using Javascript/jquery. I created an array using span elements and am looping over each letter to first change its color red and then back to black again. The problem is that the $.each loop function doesn't wait for setTimeout to finish...it loops over all of them instantly making them all turn red instantly instead of one by one. Any ideas how to fix this? Here is my code:

JSFiddle: /

var array = $(".one");

var doIt = function () {
    $.each(array, function(index, value){
            array.eq(index).css('color','red');
        setTimeout(function(){
            array.eq(index).css('color','black');                                
        }, 500);
    });

};

doIt();
P {
    color:black;
}
<script src=".11.1/jquery.min.js"></script>
<p>
    <span class="one">H</span><span class="one">e</span><span class="one"></span><span class="one">l</span><span class="one">l</span><span class="one"></span><span class="one">o</span><span class="one"> M</span><span class="one"></span><span class="one">y </span><span class="one">N</span><span class="one"></span><span class="one">a</span>
</p>

I'm trying to get a row of letters to light up one by one using Javascript/jquery. I created an array using span elements and am looping over each letter to first change its color red and then back to black again. The problem is that the $.each loop function doesn't wait for setTimeout to finish...it loops over all of them instantly making them all turn red instantly instead of one by one. Any ideas how to fix this? Here is my code:

JSFiddle: http://jsfiddle/john23/8chu18k9/

var array = $(".one");

var doIt = function () {
    $.each(array, function(index, value){
            array.eq(index).css('color','red');
        setTimeout(function(){
            array.eq(index).css('color','black');                                
        }, 500);
    });

};

doIt();
P {
    color:black;
}
<script src="https://ajax.googleapis./ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<p>
    <span class="one">H</span><span class="one">e</span><span class="one"></span><span class="one">l</span><span class="one">l</span><span class="one"></span><span class="one">o</span><span class="one"> M</span><span class="one"></span><span class="one">y </span><span class="one">N</span><span class="one"></span><span class="one">a</span>
</p>

Share Improve this question edited Jan 26, 2015 at 17:57 taesu 4,5805 gold badges26 silver badges41 bronze badges asked Jan 26, 2015 at 17:26 John23John23 1992 gold badges6 silver badges15 bronze badges 1
  • 1 you should set the timeout properly while doing so.. try to set it like this setTimeout(....., 500 * (index +1)); ............ The problem in existing logic is that it is setting timeout for all characters at same time in loop so even though it is technically setting it for each character separetly, but effect is not recognized due to fast execution. – K D Commented Jan 26, 2015 at 17:33
Add a ment  | 

3 Answers 3

Reset to default 2

setTimeout is asynchronous. It will return control back to the calling context immediately, so this code will not work as expected. I suggest using setInterval instead, which runs the same function repeatedly, at the given interval:

var array = $('.one');
var currentIndex = 0;
var intervalId = setInterval(function(){
  array[currentIndex].css('color','black');
  currentIndex++;
  // We've reached the end of the array, stop calling this function
  if (currentIndex == array.length) clearInterval(intervalId);
}, 500);

To clarify a little: setInterval will return an ID. You can then pass that ID to the function clearInterval to stop the invocation of the function.

This is what you want: http://jsfiddle/8chu18k9/1/

var array = $(".one");
var i = 0;

var doIt = function () {

    setTimeout(loopIt, 500)       
};

var loopIt = function() {

    if(i < array.length) {
        console.log("inner loop")
          array.eq(i).css('color','red');   
        if(i > 0) {
            array.eq(i-1).css('color','');               
        }        
        i++
        setTimeout(loopIt, 500)
    }    
}


doIt();

If you don't want the letters to go back to black, delete:

 if(i > 0) {
     array.eq(i-1).css('color','');               
 }        

In case you want the setTimeout solution. Here it is.

Html:

<p>
  <span class="one">H</span>
  <span class="one">e</span>
  <span class="one">l</span>
  <span class="one">l</span>
  <span class="one">o</span>
  <span class="one"> M</span>
  <span class="one">y </span>
  <span class="one">N</span>
  <span class="one">a</span>
</p>
<script src="//code.jquery./jquery-1.11.2.min.js"></script>

Css:

P {
    color:black;
}

Js:

var delayBase = 10;
var baseDuration = 500; //Time at which each span stays red for

$(document).ready(function(){
  $(".one").each(function(){
    flash($(this), delayBase, baseDuration);
    delayBase+=1000;
  });
});

function flash($element, delay, flashDuration){ 
  //set red
  setTimeout(function(){
    $element.css('color', 'red');
  }, delay );
  //set black
  setTimeout(function(){
    $element.css('color', 'black');
  }, (delay+flashDuration) );
}

codepen example: http://codepen.io/anon/pen/zxzeKE

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744250026a4565125.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信