2013-04-08 52 views
1

我寫了一個jQuery插件,它在div中獲取一個數字,然後使其數起來。我試圖添加一個回調,所以當它完成後,然後開始下一個div。如何在jquery回調中更改'this'

當它開始在下一個div上工作時,它首先重置當前div中的數字,然後按照預期繼續進行下一個div。我懷疑它與插件內部的'this'有關。

Here is a full (not) working example -->

如何防止這種情況的發生?由於

我的插件:

(function($) { 
$.fn.countUp = function(options) { 

    var settings = $.extend({ 
     'startFrom'  : 0, 
     'countTo'  : Number(this.text()), 
     'start'   : 10, 
     'frequency'  : 200, 
     'jump'   : 1, 
     'target'  : this, 
     'log'   : false, 
     'callback'  : '' 
    }, options); 

    var intRegex = /^\d+$/; 
    if(intRegex.test(settings.countTo) && intRegex.test(settings.startFrom)) { 
     // Both settings are integers, get started: 
     if(settings.startFrom<settings.countTo){ 
      offset = settings.jump; 
     }else{ 
      offset = -1 * settings.jump; 
     } 
     current_number = settings.startFrom; 
     settings.target.html(current_number); 

     checkNumber(); 
     var timer; 
     function checkNumber(){ 
      if(offset<0){ 
       if(current_number <= settings.countTo) 
       { 
        current_number = settings.counTo; 
        clearTimeout(timer); 
        if (typeof settings.callback == 'function') { // make sure the callback is a function 
         settings.callback.call(this); // brings the scope to the callback 
        } 
       } 
       else 
       { 
        current_number += offset; 
        timer=setTimeout(function(){checkNumber()},settings.frequency); 
       } 
      }else{ 
       if(current_number >= settings.countTo) 
       { 
        current_number = settings.counTo; 
        clearTimeout(timer); 
        if (typeof settings.callback == 'function') { // make sure the callback is a function 
         settings.callback.call(this); // brings the scope to the callback 
        } 
       } 
       else 
       { 
        current_number += offset; 
        timer=setTimeout(function(){checkNumber()},settings.frequency); 
       } 
      } 
      settings.target.html(current_number); 
      if(settings.log){console.log(settings.target.attr('id'))}; 
     } 

    }else{ 
     if(settings.log){console.log('From countUp: Please use an integer for startFrom and countTo arguments.');} 
    } 
}; 
})(jQuery); 

這裏是我怎樣,我稱之爲:

$(document).ready(function(){ 
    $("#output").countUp({ 
     'log' : true, 
     'callback' : call2 
    }); 

    function call2(){ 
     $("#output2").countUp({ 
      'log' : true, 
      'callback' : call3 
     }); 
    } 

    function call3(){ 
     $("#output3").countUp({'log' : true}); 
    } 
}) 
+0

回調函數的目的,不是簡單地讓你的插件再次做同樣的事情。它就在那裏,因此您可以在插件正在處理某些事情時完成一些臨時結果,或者在完成異步任務後處理這些結果。要做你想做的事,你可以連續調用插件3次。但是,讓我們說這是有用的,因爲計數發生異步。然後,對於初學者,請嘗試將回調重命名爲onFinished或其他。有意義的命名將幫助你更好地理解你在做什麼。 – 2013-04-08 20:39:40

+0

另外,似乎沒有必要爲'settings.callback.call(this)添加一個參數;'如果我沒有弄錯,你可以'settings.callback()'。 – 2013-04-08 20:46:47

+0

如果我連續三次調用插件,它們都會同時執行。我試圖通過在插件中使用回調函數或onFinished函數來開始下一個動畫,從而使插件一個接一個地執行。我已經做了一切建議,但onFinished函數仍然干擾以前的div http://codepen.io/sheepysheep60/pen/jxudC – Djave 2013-04-08 20:53:56

回答

0

某些變量正在從設置創建的,但它們並沒有被清除。通過添加這些變量中的每一個的var infront,範圍將停留在該函數內並解決問題。

(function($) { 
$.fn.countUp = function(options) { 

var settings = $.extend({ 
    'startFrom'  : 0, 
    'countTo'  : Number(this.text()), 
    'start'   : 10, 
    'frequency'  : 200, 
    'jump'   : 1, 
    'target'  : this, 
    'log'   : false, 
    'callback'  : '' 
}, options); 

var intRegex = /^\d+$/; 
if(intRegex.test(settings.countTo) && intRegex.test(settings.startFrom)) { 
    // Both settings are integers, get started: 
    if(settings.startFrom<settings.countTo){ 
     offset = settings.jump; 
    }else{ 
     offset = -1 * settings.jump; 
    } 
    current_number = settings.startFrom; 
    settings.target.html(current_number); 

    checkNumber(); 
    var timer; 
    function checkNumber(){ 
     if(offset<0){ 
      if(current_number <= settings.countTo) 
      { 
       current_number = settings.counTo; 
       clearTimeout(timer); 
       if (typeof settings.callback == 'function') { // make sure the callback is a function 
        settings.callback.call(this); // brings the scope to the callback 
       } 
      } 
      else 
      { 
       current_number += offset; 
       timer=setTimeout(function(){checkNumber()},settings.frequency); 
      } 
     }else{ 
      if(current_number >= settings.countTo) 
      { 
       current_number = settings.counTo; 
       clearTimeout(timer); 
       if (typeof settings.callback == 'function') { // make sure the callback is a function 
        settings.callback.call(this); // brings the scope to the callback 
       } 
      } 
      else 
      { 
       current_number += offset; 
       timer=setTimeout(function(){checkNumber()},settings.frequency); 
      } 
     } 
     settings.target.html(current_number); 
     if(settings.log){console.log(settings.target.attr('id'))}; 
    } 

}else{ 
    if(settings.log){console.log('From countUp: Please use an integer for startFrom and countTo arguments.');} 
} 
}; 
    })(jQuery); 
0

設置爲this

var $this = this; 

範圍之外創建一個變量將解決這個問題,如果我正確地閱讀問題。 this將被功能範圍覆蓋。

UPDATE

僅供參考,有一個在您的代碼一個錯字:

current_number = settings.counTo; 

我認爲它應該是settings.countTo

編輯的代碼

(function($) { 
$.fn.countUp = function(options) { 

    var $this = this; 

    var settings = $.extend({ 
     'startFrom'  : 0, 
     'countTo'  : Number($this.text()), 
     'start'   : 10, 
     'frequency'  : 200, 
     'jump'   : 1, 
     'target'  : $this, 
     'log'   : false, 
     'callback'  : '' 
    }, options); 

    var intRegex = /^\d+$/; 
    if(intRegex.test(settings.countTo) && intRegex.test(settings.startFrom)) { 
     // Both settings are integers, get started: 
     if(settings.startFrom<settings.countTo){ 
      offset = settings.jump; 
     }else{ 
      offset = -1 * settings.jump; 
     } 
     current_number = settings.startFrom; 
     settings.target.html(current_number); 

     checkNumber(); 
     var timer; 
     function checkNumber(){ 
      if(offset<0){ 
       if(current_number <= settings.countTo) 
       { 
        current_number = settings.counTo; 
        clearTimeout(timer); 
        if (typeof settings.callback == 'function') { // make sure the callback is a function 
         settings.callback.call($this); // brings the scope to the callback 
        } 
       } 
       else 
       { 
        current_number += offset; 
        timer=setTimeout(function(){checkNumber()},settings.frequency); 
       } 
      }else{ 
       if(current_number >= settings.countTo) 
       { 
        current_number = settings.counTo; 
        clearTimeout(timer); 
        if (typeof settings.callback == 'function') { // make sure the callback is a function 
         settings.callback.call($this); // brings the scope to the callback 
        } 
       } 
       else 
       { 
        current_number += offset; 
        timer=setTimeout(function(){checkNumber()},settings.frequency); 
       } 
      } 
      settings.target.html(current_number); 
      if(settings.log){console.log(settings.target.attr('id'))}; 
     } 

    }else{ 
     if(settings.log){console.log('From countUp: Please use an integer for startFrom and countTo arguments.');} 
    } 
}; 
})(jQuery); 
+0

如果我錯了,請原諒我,但是這不是什麼「目標」:這,「在做什麼?謝謝 – Djave 2013-04-08 20:28:10

+0

我想我不確定你的插件的目標是什麼。你能澄清嗎? – 2013-04-08 20:32:49

+0

感謝您的幫助。如果你看看我提供的鏈接,它只是計數從0到div中的數字。然後當它到達那個數字時,從0開始計數下一個div。所提供的鏈接應該以「10,10,10」結束,但在運行腳本時此刻結束「1,1,10」 – Djave 2013-04-08 20:36:25

相關問題