循环css样式与setTimeout: "在眨眼之间"

Looping css style with setTimeout: "in the blink of an eye"

本文关键字:quot 之间 css 样式 setTimeout 循环      更新时间:2023-09-26

我想让一个条(#innerBar)的宽度每秒减小1%。

循环似乎不起作用。我的条在眨眼间从100%下降到0%。

function timer(){
    var timer;
    for(i=100;i>=0;i--){
        timer = i.toString() + "%";
        setTimeout(function({$('#innerBar').css("width", timer)}, ((100-i)*1000));
    }
}

注意:#innerBar是一个DIV的css属性(height:10px)。** +从定时器()的宽度;* *

正如在评论中已经说过的,您需要将它放在闭包中。下面是一个例子:

function timer() {
  for (i = 100; i >= 0; i--) {
    setTimeout(function(t) {
      return function() {
        var timer = t.toString() + "%";
        $('#innerBar').css("width", timer);
      };
    }(i), ((100 - i) * 1000));
  }
}
timer();
#innerBar {height: 50px; background: green; transition: width 0.2s linear}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="innerBar"></div>


解释

所以我的问题是:函数(t)发生了什么?}(i)为什么起作用?如何起作用?它是fu的乘法吗?

让我们取传递给setTimeout的函数体:

function(t) {
  return function() {
    var timer = t.toString() + "%";
    $('#innerBar').css("width", timer);
  };
}(i)

让我们省略里面的部分:

function(t) {
   // do some stuff with t
}(i)

看起来熟悉吗?就像函数体被立即调用一样,它被称为IIFE,就像:

(function(a, b) {
    return a + b;
})(2, 3)  // returns 5

那么回到原来的函数,它接受一个参数t,当我们调用函数时,我们将迭代器i作为参数传递给它(所以i的值在函数中变成了t)。正如我在评论中所说,为了"获取"i的当前值而不是获取循环后的值,这是必要的。

@Shomz已经发过了。这是个很好的解决方案。我只是想添加我的解决方案,因为它没有创建100个函数。所以它在内存上稍微轻一些。此外,您不必一遍又一遍地查看DOM中的#innerBar。我删除了jQuery作为依赖项。

var size = 100;
var bar = document.getElementById( "innerBar" );
function setSize() {
    bar.style.width = size-- + "%";
    if ( size > 0 ) setTimeout( setSize, 1000 );
}
    
setSize();
#innerBar {
    width: 100%;
    height: 50px; 
    background: green; 
    transition: width 0.2s linear;
}
<div id="innerBar"></div>

我认为下面的代码可以满足您的要求。输入时间应为1000,这将使宽度每秒减少1%

  var width = $('#innerBar').width();
  function timeLoop(time){
      width = width*0.99;
      $('#innerBar').css("width", width);
      if (width <= 0.01){
          return;
      }
      else {
          setTimeout(function() {
              timeLoop(time);
          }, time);
      }
  }