2012-11-21 96 views
5

這裏的jsfiddle模擬與此代碼我的問題:爲什麼所有迭代都在同一時間運行?

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

我期待#img1元素淡入,然後執行停1秒鐘,然後淡出,然後重新開始爲#img2元素等

+0

爲什麼你會想到什麼? fadeIn是一個同步調用,所以它不一定等待它完成。 – dchhetri

+2

@ user814628,我認爲你的意思是說「異步調用」,而不是「同步調用」 – Brad

+2

@ user814628:也許是因爲用戶真的不知道'.fadeIn'或jQuery中的其他效果函數是異步的。異步執行在JavaScript中很常見,特別是在現代JS框架中,但每個人都必須在某個時候第一次瞭解它。這是一個很好的問題,不僅適用於jQuery中的動畫效果,也適用於理解AJAX和Backbone.js模型拾取(這實際上也是AJAX的抽象,但不必介意)。不要因爲不知道而反感用戶;相反,提供一個答案並教:-) –

回答

7

動畫似乎同時運行的原因是jQuery的動畫都是異步執行的。所以你的代碼正在做的是基本上開始所有的動畫,然後你的瀏覽器幾乎同時處理實際的動畫。

但是,jQuery的動畫函數確實支持使用在動畫完成後調用的回調函數。通過確保後面的動畫在這個回調中發生,我們可以強制動畫順序執行。

這裏,你可以實現你的要求(jsfiddle here)的一種方法:

$('#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(); 
}); 

請注意,我排隊再次調用animate()的回調.fadeOut。然後該函數將重新執行,但數組的狀態將在每個函數調用中發生變化,以便每個元素都按順序執行一次動畫。當數組被清除時,函數將只運行一次以驗證元素全部是動畫的,在這種情況下,它將返回而不重新排隊。

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'維持其間隔的能力。這個答案的另一個問題是,即使所有圖像都已經過動畫處理(在每個後面的情況下進行比較和返回),「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

是的,非常真實我給了你+1,因爲這已經可能運行在匿名函數(用於'$(document).ready()'/'$()')。 –

相關問題