【问题标题】:get SetTimeout to finish before continuing loop在继续循环之前完成 SetTimeout
【发布时间】:2015-03-25 04:13:45
【问题描述】:

我正在尝试使用 Javascript/jquery 逐个点亮一排字母。我使用 span 元素创建了一个数组,并在每个字母上循环以首先将其颜色更改为红色,然后再次变回黑色。问题是 $.each 循环函数不会等待 setTimeout 完成......它会立即循环所有它们,使它们立即变为红色,而不是一个接一个。任何想法如何解决这一问题?这是我的代码:

JSFiddle:http://jsfiddle.net/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.com/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>

【问题讨论】:

  • 你应该在这样做的时候正确设置超时..尝试像这样设置它 setTimeout(....., 500 * (index +1)); .......... 现有逻辑中的问题是它在循环中同时为所有字符设置超时,因此即使在技术上为每个字符单独设置超时,但由于无法识别效果快速执行。

标签: javascript jquery loops settimeout


【解决方案1】:

setTimeout 是异步的。它将立即将控制权返回给调用上下文,因此此代码将无法按预期工作。我建议改用setInterval,它以给定的时间间隔重复运行相同的函数:

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

澄清一点:setInterval 将返回一个 ID。然后,您可以将该 ID 传递给函数 clearInterval 以停止该函数的调用。

【讨论】:

    【解决方案2】:

    这就是你想要的:http://jsfiddle.net/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(i > 0) {
         array.eq(i-1).css('color','');               
     }        
    

    【讨论】:

      【解决方案3】:

      如果您需要 setTimeout 解决方案。在这里。

      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.com/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 示例:http://codepen.io/anon/pen/zxzeKE

      【讨论】:

      • 好主意..增加每个循环后的持续时间。谢谢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-12-26
      • 1970-01-01
      • 2021-10-19
      • 1970-01-01
      • 1970-01-01
      • 2012-04-05
      • 2021-11-26
      相关资源
      最近更新 更多