Javascript setTimeout,循环和关闭

时间:2013-03-12 14:05:24

标签: javascript settimeout

以下代码让我感到困惑。我的目标是在一段时间内将HTML元素从一个不透明度级别淡化到另一个级别。下面是我的dimScreen()方法,用于创建一个黑暗的叠加层并将其淡入。

var overlay;

function dimScreen()
{
   if(!overlay)
   {
      overlay = document.createElement('div');
      overlay.setAttribute('id', 'overlay');
      overlay.style.width = '100%';
      overlay.style.height = '100%';
      overlay.style.zindex = '1000';
      overlay.style.background = '#000013';
      overlay.style.position = 'fixed';
      overlay.style.left = '0';
      overlay.style.top = '0';
      overlay.style.opacity = '.0';

      document.body.appendChild(overlay);
      fade('overlay', 0, 75, 200);
   }
}

这是我的工作淡入淡出功能:

function fade(eID, startOpacity, stopOpacity, duration)
{
   var speed = Math.round(duration / 100);
   var timer = 0;
   if (startOpacity < stopOpacity)
   {     // fade in
      for (var i=startOpacity; i<=stopOpacity; i++)
      {
         setTimeout("setOpacity('"+eID+"',"+i+")", timer * speed);
         timer++;
      } return;
   }
   for (var i=startOpacity; i>=stopOpacity; i--)
   {     // fade out
      setTimeout("setOpacity('"+eID+"',"+i+")", timer * speed);
      timer++;
   }
}

我的工作setOpacity:

function setOpacity(eID, opacityLevel)
{
   var eStyle = document.getElementById(eID).style;
   eStyle.opacity = opacityLevel / 100;
   eStyle.filter = 'alpha(opacity='+opacityLevel+')';
}

但是,我希望将我的fade()函数更改为以下形式使用闭包:

setTimeout(function(){setOpacity(eID,i)}, timer * speed);

然后我可以传入实际的叠加div,而不是id'overlay'。但是,当我这样做时,不是动画叠加div的逐渐淡入,而是直接到最后的不透明度值,没有过渡。为什么会这样?

我觉得这很简单,我很遗憾,因为我已经看了很久了。任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

这太晚了,现在太热了,不能在这里思考太多。 (上午2:30,28°C) 如果我的解释达不到预期,请原谅我。

基本上,因为您构造要传递给setTimeout的文本字符串,所以每次调用都会获得正确的i值。由于传递一个实际的元素,你不能使用字符串技巧,你最终使用相同的i值来调用setOpacity。

正如您的问题标题表明您理解,您需要使用闭包来使其正常工作。我找不到(仅遵循2或3个链接)一个好的tute / S.O问题,以一种看似相关且清晰的方式解释它。

希望代码可以使用。

var overlay;
function dimScreen()
{
   if(!overlay)
   {
      overlay = document.createElement('div');
      overlay.setAttribute('id', 'overlay');
      overlay.style.width = '100%';
      overlay.style.height = '100%';
      overlay.style.zindex = '1000';
      overlay.style.background = '#000013';
      overlay.style.position = 'fixed';
      overlay.style.left = '0';
      overlay.style.top = '0';
      overlay.style.opacity = '.0';

      document.body.appendChild(overlay);
      myFade(overlay, 0, 75, 2000);
   }
}
function myFade(element, startOpacity, stopOpacity, duration)
{
   var speed = Math.round(duration / 100);
   var timer = 0;
   if (startOpacity < stopOpacity)
   {     // fade in
      for (var i=startOpacity; i<=stopOpacity; i++)
      {
        (
            function()
            {
                var myI = i;
                setTimeout(function(){mySetOpacity(element,myI)}, timer * speed);
            }
        )()
         timer++;
      }
   }

   else
   for (var i=startOpacity; i>=stopOpacity; i--)
   {     // fade out
      for (var i=startOpacity; i<=stopOpacity; i++)
      {
        (
            function()
            {
                var myI = i;
                setTimeout(function(){mySetOpacity(element,myI)}, timer * speed);
            }
        )()
         timer++;
      }
   }
}

function mySetOpacity(el, opacityLevel)
{
   var eStyle = el.style;
   eStyle.opacity = opacityLevel / 100;
   eStyle.filter = 'alpha(opacity='+opacityLevel+')';
}