2012-09-27 31 views
4

我試圖通過執行上一個函數後執行下一個函數來產生連鎖反應。代碼如下所示:上次完成時無法觸發下一個函數

var med = { 

    imgLoadTime : 2000, 

    easingEffect : 'easeOutQuart', 

    scrollEase : 'easeInOutQuad', 

    effectDuration : 1000, 

    currentPage : '', 

    runAnimations : function(){ 
         if(this.currentPage == '#slide5'){ 
          this.initAssets(); 
         } 
        }, 

    initAssets : function(){ 
        $('#asset-1').animate(
         {left : '50%'}, 
         { 
          duration: this.effectDuration, 
          easing: this.easingEffect, 
          complete: this.assetTwo 
         }); 
       }, 

    assetTwo : function(){ 
        console.log('two'); 
        debugger; 
        $('#asset-2').animate(
         {left : '50%'}, 
         { 
          duration: this.effectDuration, 
          easing: this.easingEffect, 
          complete: this.assetThree 
         }); 
       }, 

    assetThree : function(){ 
        console.log('three'); 
        $('#asset-3').animate(
         {left : '50%'}, 
         { 
          duration: this.effectDuration, 
          easing: this.easingEffect, 
          complete: console.log('weszlo') 
         }); 
       } 

}; 

這就是我的對象的外觀。然後我運行函數runAnimations作爲對象的一個​​屬性。奇怪的是,在這個鏈中只有asset兩個函數執行,但沒有進一步(assetThree)。爲什麼這樣?

回答

3

你不能做這種類型的定義:

complete: this.assetTwo 

它將調用assetTwo,但不會有正確的this值。相反,您需要這樣做:

  initAssets : function(){ 
       var self = this; 
       $('#asset-1').animate(
        {left : '50%'}, 
        { 
         duration: this.effectDuration, 
         easing: this.easingEffect, 
         complete: function() {self.assetTwo()} 
        }); 
      }, 

其他完整功能相同。您需要將this的值保存到局部變量中,然後在完整的函數中使用它來調用下一個方法。這將確保爲下一個方法正確設置this

+0

+1 - 擊敗我吧。另一個'self = this'的例子! :)'self = this'的原因是因爲OP認爲他們的目標是'this'的父母仍然保留子函數中'self'的範圍。 –

+0

謝謝!再次是範圍問題。 ech,可愛的js;) – lukaleli

+1

@ lesny09 - this'的值由調用者設置。在動畫完整函數中,'this'可能被設置爲正在動畫的對象。因此,在你的原始代碼發生完成並且調用了assetTwo()時,'this'不會被設置爲你的對象,而是被設置爲動畫的#asset-1。這會弄亂動畫中的下一個項目,因爲'this.assetThree()'不會存在,因爲它是錯誤的'this'。由於它不存在,它會停止序列。將正確的值保存到局部變量中,並使用該變量保證它獲得正確的「this」。 – jfriend00

0

使用med而不是this在你所有的地方javascript代碼。

1

你這改變了每個功能,您可以通過med,而不是引用它來得到期望的結果:

assetTwo : function(){ 

       //debugger; 
       $('#asset-2').animate(
        {left : '50%'}, 
        { 
         duration: med.effectDuration, 
         easing: med.easingEffect, 
         complete: med.assetThree 
        }); 
      }, 

更新小提琴:http://jsfiddle.net/johnkoer/2KHnc/16/

0

對於漂亮的緊身代碼中使用jQuery的$.Deferred.pipe()鏈描述here

你應該最終得到類似這樣的結果:

var med = { 
    imgLoadTime: 2000, 
    currentPage: '', 
    css : {left: '50%'}, 
    animOptions: { 
     duration: 1000, 
     easing: 'easeOutQuart' 
    }; 
    runAnimations: function() { 
     if(med.currentPage == '#slide5') { 
      $.Deferred(function(dfr) { 
       dfr.pipe(function() { 
        return $('#asset-1').animate(med.css, med.animOptions); 
       }).pipe(function() { 
        return $('#asset-2').animate(med.css, med.animOptions); 
       }).pipe(function() { 
        return $('#asset-3').animate(med.css, med.animOptions); 
       }) 
      }).resolve(); 
     } 
    } 
}; 

未經檢驗

獲取Deferreds的竅門,你永遠不會回頭。

除非med對象是其他重要的原因,那麼這將是簡單的只是有runAnimations()而不是一個對象包裝:

function runAnimations() { 
    var imgLoadTime = 2000, 
    currentPage = '', 
    css = {left: '50%'}, 
    animOptions = { 
     duration: 1000, 
     easing: 'easeOutQuart' 
    }; 
    if(currentPage == '#slide5') { 
      $.Deferred(function(dfr) { 
       dfr.pipe(function() { 
        return $('#asset-1').animate(css, animOptions); 
       }).pipe(function() { 
        return $('#asset-2').animate(css, animOptions); 
       }).pipe(function() { 
        return $('#asset-3').animate(css, animOptions); 
       }) 
      }).resolve(); 
    } 
} 

這種方式引用到固定的參數非常簡單。

+0

編輯簡化代碼 –

相關問題