如何在jquery回调中更改'this'

时间:2013-04-08 20:21:21

标签: jquery plugins this

我编写了一个jQuery插件,它接受div中的数字然后使其计数。我试图添加一个回调,所以当它完成它然后开始下一个div。

当它开始处理下一个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});
    }
})

2 个答案:

答案 0 :(得分:0)

创建一个在this

范围之外的变量
var $this = this;

如果我正确地阅读问题,这将解决问题。 this将被函数范围覆盖。

<强>更新

仅供参考,您的代码中存在拼写错误:

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 );

答案 1 :(得分:0)

某些变量是根据设置创建的,但它们并未被清除。通过在每个变量的前面添加var,范围保留在函数内并修复了问题。

(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 );