jQuery插件,context和setTimeout

时间:2011-01-03 19:25:35

标签: javascript jquery this settimeout

我正在为jQuery编写一个插件,我在javascript中遇到了上下文问题。

这是我的插件的简化版本:

(function($){  

$.fn.myplugin = function(options){
    return new MyPlugin(this, options);
};


function MyPlugin(el, o )
{
    this.root    = el;
    this.input_box = el.find('#the_input');
    this.map = null;
    this.timeout = null;
    var self = this;

    self.input_box.keyup( function(){
    if( self.timeout!==null )
    {
       clearTimeout( self.timeout );
    }
    self.timeout = setTimeout( function(){
            self.search_address( self );
            }, 500 );
    });
}

MyPlugin.prototype = {

    search_address : function( context ){
          geocoder.geocode({'address':$('#direction').val()}, 
             function( results, status ){
              var lat = results[0].geometry.location.lat();
              var lng = results[0].geometry.location.lng();
              var latlng = new google.maps.LatLng( lat, lng );

              context.select_address( latlng, '' );                                   
    },

    select_address : function( latlng, text ){
        self.root.find('#url').val('http://maps.google.com/?q='+encodeURI($('#direccion').val())+'&ll='+coords.lat()+','+coords.lng()+'&ie=UTF8&oe=UTF8&z=18');
    }
};
})(jQuery);

我已经读过setTimeout将上下文设置为全局对象,所以我做了闭包以便能够将上下文传递给search_address函数。这允许我从select_address函数中的回调中调用geocode,但此回调调用了select_address,并且上下文再次出现意外情况:找不到self.root

我完全不知道如何处理上下文,虽然在初始化“对象”时使用var self=this我会避免这些问题......

我必须注意select_address可以直接调用...

2 个答案:

答案 0 :(得分:1)

此时使用this来引用当前上下文:

select_address : function( latlng, text ){
    this.root.find('#url').val('http://maps.google.com/?q='+encodeURI($('#direccion').val())+'&ll='+coords.lat()+','+coords.lng()+'&ie=UTF8&oe=UTF8&z=18');
}

答案 1 :(得分:1)

我刚刚发现了一些很酷的东西来修复jQuery 1.4 +中的SetTimeout上下文。

您可以使用jQuery.proxy来解决上下文问题。

这是我的代码:


    Application = function()
    {
        this.AMethod = function(){};

        setTimeout($.proxy(this.AMethod,this), 100);


    }

超时后,执行Application.AMethod,从而维护“Application”上下文

LE: 或者,如果您不希望自己的插件仅限于jQuery 1.4+,则可以非常简单地创建自己的代理函数:


    function proxy(func, context)
    {
        return function(){ return func.apply(context, arguments);}
    }