1

次のコードは私を混乱させました。私の目標は、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);

次に、id'overlay'の代わりに、実際のoverlaydivを渡すことができます。ただし、これを行うと、オーバーレイdivの段階的なフェードインをアニメートするのではなく、遷移なしで最後の不透明度の値に正しく移動します。なぜこれが起こるのですか?

ずっと見ていたので、これは単純なことで、見落としているような気がします。どんな助けでもいただければ幸いです!

4

1 に答える 1

0

今ここで多くを考えるには遅すぎてまだ暑すぎます。(2.30am、28°C)私の説明が期待を下回ったら許してください。

基本的に、setTimeoutに渡すテキスト文字列を作成するため、各呼び出しはiの正しい値を取得します。実際の要素を渡すために文字列トリックを使用することはできないため、setOpacityの呼び出しごとに同じ値のiを使用することになります。

質問のタイトルが理解していることを示しているので、正しく機能させるにはクロージャを使用する必要があります。関連性があり明確に見える方法でそれを説明する良いtute/SOの質問を見つけることができません(2つまたは3つのリンクをたどっただけです)。

コードが役立つことを願っています。

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+')';
}
于 2013-03-12T15:42:36.130 に答える