2012-11-21 12 views
5

は、このコードに関連する私の問題をシミュレートjsfiddleです:すべての反復が同時に実行されるのはなぜですか?ここ

$('#button').click(function(){ 
    var i; 
    for (i = 1; i < 4; ++i) { 
     $('#img' + i).fadeIn("slow").delay(1000); 
     $('#img' + i).fadeOut("slow"); 
    } 
}); 

私がフェードインし、その後の実行のために1秒間停止してからフェードアウトし、その後、#img2ため、最初からやり直す#img1要素を期待していました要素など

+0

のような新しい画像番号でコールバックを呼び出していますか? fadeInは同期呼び出しであるため、必ずしも完了するまで待つ必要はありません。 – dchhetri

+2

@ user814628、私はあなたが "同期呼び出し"ではなく "非同期呼び出し"と言っていると思うと思います。 – Brad

+2

@ user814628:おそらく、ユーザーが本当にjQueryの '.fadeIn'やその他のエフェクト関数が非同期である。非同期実行は、JavaScript、特に現代のJSフレームワークでは一般的ですが、誰かがいつかそれについて最初に学ばなければなりません。これは、jQueryのアニメーション効果だけでなく、AJAXやBackbone.jsモデルのフェッチ(実際にはAJAXの抽象でもありますが、気にすることはありません)を理解する上でも有効な質問です。ユーザーに知らないことを知らせないでください。代わりに、答えを教えて:-) –

答えて

7

アニメーションが同時に実行されるように見える理由は、jQueryのアニメーションがすべて非同期に実行されるためです。だから、あなたのコードがやっていることは基本的にすべてのアニメーションを開始することです、そして、あなたのブラウザは実際のアニメーションをほぼ同時に扱います。

jQueryのアニメーション関数は、アニメーションが終了した後に呼び出されるコールバックの使用をサポートしています。後のアニメーションがこのコールバックで確実に行われるようにすることで、アニメーションを強制的に強制的に実行することができます。私は.fadeOutのコールバックとしてanimate()に別のコールをキューイングしてい

$('#button').click(function(){ 
    var i; 
    var $elems = []; 
    for (i = 1; i < 4; ++i) { 
     $elems.push($('#img' + i)); 
    } 

    var animate = function() { 
     var $elem; 
     if ($elems.length) { 
      $elem = $elems.shift(); 
      $elem.fadeIn("slow").delay(1000).fadeOut("slow", animate); 
     } 
     // if the $elems has been cleared out, we're done and this function won't be requeued 
    }; 

    animate(); 
}); 

注:

は、ここでは、あなたの要件(jsfiddle here)を実装することができます一つの方法です。この関数は再実行されますが、$elems配列の状態は各関数呼び出しで変更されるため、各要素のアニメーションは1回実行されます。配列がクリアされると、関数はもう一度実行され、要素がすべてアニメ化されていることを確認します。その場合は、再度キューに入れずに戻ります。

1

これを試してください:

我々はできないforループ内フェードイン()遅延を使用します。

代わりにsetInterval()を使用できます。

次のコードを試してください。

var i; 
var timeMgt; 

$('#button').click(function(){ 
    i = 1; 
    timeMgt = setInterval(ChangeImage,1000); 
}); 

function ChangeImage() 
{ 
    if(i<4) 
    { 
     $('#img' + i).fadeIn("slow").delay(1000); 
     $('#img' + i).fadeOut("slow"); 
     i++; 
    } 
    else 
    { 
     window.clearInterval(timeMgt); 
     return; 
    } 
} 
+0

なぜsetIntervalに文字列引数を使用するのですか?なぜ関数名を渡すだけではないのですか? –

+0

画像の変更ごとに1秒の時間間隔を維持する必要があるためです。 ChangeImage()関数はそれぞれ1秒を呼び出します。 –

+1

@ suresh。g:実際の関数オブジェクト(関数名または無名関数のいずれか)を 'setInterval'や' setTimeout'の引数として使うことができます。そうすれば、文字列に 'eval'を走らせる落とし穴を避けることができます。セキュリティ上のリスクの他に、遅い)。関数オブジェクトを使用することは決して 'setInterval'の間隔を維持する能力に影響しません。この答えのもう1つの問題は、すべての画像がアニメートされた後でも(ChangeImageが実行されても)、リソースの浪費であることです。 –

1

fadeIn関数とfadeOut関数でコールバックを利用したいと思うでしょう。例はhttp://jsfiddle.net/JaQmd/5/です。

あなたはそれを期待するのはなぜコードの心臓部は、基本的にはそう

var imageNumber = 0; 

$('#button').click(function doAnimation() { 
++imageNumber; 
if(imageNumber <= 3){ 
    $("#img" + imageNumber).fadeIn('slow').delay(1000); 
    $("#img" + imageNumber).fadeOut('slow', doAnimation); 
    } 
});​ 
+0

あなたは本当にそのグローバルな 'imageNumber'を必要としませんか? :-(そうでなければ全体的にまともな解決策です(これも '$(document).ready(function(){/ * ... * /});で実行されるとしたら、あなたは大丈夫かもしれません) –

+0

これは単純化のため、引数として渡したいと思っていた方がよい場合は、さらに変数をカプセル化することができます。 – dchhetri

+1

ええ、本当です。無名関数( '$(document).ready()'/'$()')のためのものです。 –

関連する問題