【问题标题】:JavaScript: setTimeout not updating value inside loopJavaScript:setTimeout 不更新循环内的值
【发布时间】:2016-05-30 01:02:36
【问题描述】:

我知道关闭,IIFE。
我已经阅读了其他答案(他们都指向使用 IIFE)。
那么为什么这不起作用呢?

  • 我的图像应该逐渐淡入(在 2 秒内)
  • 好像只渲染一次(带有最终值)
var imgFade = document.getElementById('img-fade');
for(i = 0; i < 100; i++){
  (function(step) {
    setTimeout(function() {
      imgFade.style.opacity = (step/100);
    }, 20);
  })(i);
}

这里是代码:https://jsfiddle.net/warkentien2/Lh10phuv/1/

编辑:供未来读者使用
考虑从 i = 1; to 1 &lt;= 100, i++ 转换的所有答案
所以它不会在 99% 时停止渲染

【问题讨论】:

  • 嗯,您实际上是在一次设置一大堆超时,以便在 20 毫秒后执行;它们都会一个接一个地以极快的速度开火。您必须稍微分散时间才能使其渐进
  • @deceze 这不是问题,或者 setTimeout 上的一个简单的额外 0 就可以解决它。
  • @warkentien2 我认为这是问题所在,因为在制作第一个 setTimeout 和最后一个之间确实存在纳秒。因此,您将看到的只是最后一个。 setInterval 可能是你需要的。
  • @deceze 似乎是对的。 settimeout 调用不会相隔 20 毫秒被调用,它们都会在 ~20 毫秒内被同时调用
  • 想一想:这个循环将在几分之一秒内运行,设置 100 个回调以在大约 20 毫秒后执行。每个回调也只需要几分之一秒,然后下一个回调运行。所以你的执行是 0% 的不透明度,循环,... 20ms 什么都没有... 1,2,3,4...100% 的不透明度在几分之一秒内。从视觉上看,这种变化似乎是瞬间的。你要么想将超时时间设置为20 * i,让每个回调越来越延迟,要么你需要在上一个回调完成20ms后触发下一个回调。

标签: javascript css closures settimeout iife


【解决方案1】:

一种快速但肮脏的方法是将20 乘以step。您一次创建所有超时,因此应该稍后执行的超时具有更高的延迟:

var imgFade = document.getElementById('img-fade');
for(i = 0; i < 100; i++){
  (function(step) {
    setTimeout(function() {
      imgFade.style.opacity = (step/100);
    }, step * 20);
  })(i);
}

【讨论】:

  • 这太棒了!传统上,人们会使用setInterval like this,但我更喜欢这个。
  • 所以我一次创建了所有的 setTimeouts!我花了一段时间才相信它。我认为它作为一个系统工作('暂停');谢谢!这根本不是一个肮脏的把戏。谢谢!
  • 请注意,这会一次向执行队列发送一百个回调。虽然在实践中可能不是一个大问题,但在前一个回调结束时安排下一个回调会更有效。它还允许您随时取消淡入,当整个事情已经安排好执行而没有真正的方法来取消一百个回调时,这有点难以做到。
  • @deceze 回调是什么意思? setTimeout 没有回调。而且,不确定我是否理解正确,但听起来仍然像一个循环。能给我发一个函数示例吗?
  • @warkentien2 回调是您传递给函数以在函数结束或一段时间后执行的任何代码。 setTimeout 是一个典型的带有回调的函数示例。
【解决方案2】:

这是另一种解决方案,一个接一个地应用淡入淡出:

var fade = function(step){
  imgFade.style.opacity = (step/100);
  if(step < 100){
    setTimeout(function(){ fade(++step); }, 20);
  }
};

fade(0);

【讨论】:

  • 不错的递归!现在我得到了问题,我可以自己想一些解决方案。但我给予了应有的信任。
  • 我认为更好的版本会使用--stepif(step &gt; 0)。这样,您可以通过更改初始参数来更改迭代次数。
  • 甜蜜,很高兴您了解它的工作原理! @4castle 是的,这肯定是一个改进
猜你喜欢
  • 1970-01-01
  • 2013-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-13
  • 1970-01-01
  • 1970-01-01
  • 2019-10-10
相关资源
最近更新 更多