jQuery插件'this.each不是函数'

时间:2011-02-26 20:08:43

标签: jquery jquery-plugins

我正在尝试创建我的第一个jQuery插件,并且我正在查找错误this.each is not a function,该错误在return this.each(function() {方法中引用此行bindUi。我认为this引用了“调用插件的jQuery对象”,在我的情况下,这是我用#location创建插件时使用的$('#location').locationSearch()节点,对吧?我在页面加载时遇到此错误。

这是我的插件代码:

(function($) {  
  var methods = {
    init : function( options ) {

      return this.each(function() {

        var settings = {
          //none yet
        };

        if ( options ) { 
          $.extend( settings, options );
        }        
        methods.log('init');

        //attach events
        methods.bindUi();        
      });

    },

    destroy : function( ) {
       return this.each(function(){ });
    },

    bindUi : function() {

      return this.each(function() {

        methods.log('bindUi');
        this.click(function() {
          methods.log('clicked');
        });

      });

    },    

    log : function(text) {
      if (window.console && window.console.log) {
        window.console.log(text);
      };
    }
} // end methods

  jQuery.fn.locationSearch = function(method) { 
    if ( methods[method] ) {
      return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
    } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
    } else {
      $.error( 'Method ' +  method + ' does not exist on jQuery.tooltip' );
    }    
  };
})( jQuery );

如果我的每个方法都需要使用return this.each(function() { ..,或者只有init和destroy方法使用它,我也有点困惑?

2 个答案:

答案 0 :(得分:4)

你必须致电

methods.bundUi.apply(this);

init方法中。

如果您只methods.bindUi()this内的bindUi将引用methods对象。

<强>更新

哦,我刚看到它。您在methods.bindUi()循环中调用each 。然后this将引用当前的 DOM元素。那么现在的问题是,你想在bindUi内引用什么?所有选定的元素,或者只是循环中的当前元素?

以下是两个可能性:

答:所有元素

init : function( options ) {
    this.each(function() {
        var settings = {
            //none yet
        };
        if ( options ) { 
            $.extend( settings, options );
        }        
        methods.log('init');   // <- this might be also better outside the loop
    });
    //attach events
    methods.bindUi.apply(this);    // <- called outside the each loop 

    return this;
}

(无需更改bindUi

B:一个元素thiseach循环内的init将引用当前的 DOM元素。我们当时只处理一个元素,因此我们不需要在each方法中使用bindUi。 (仍然在methods.bindUi.apply(this)中使用init(但在循环内部,就像你已经拥有它一样))。但是你不能再从外面打电话给bindUi了(即你不能打电话给.locationSearch('bindUi'))。

bindUi : function() {
    // don't need `each`, as `this` will refer to only one element.
    methods.log('bindUi');
    $(this).click(function() {
          methods.log('clicked');
    });
},  

第三种解决方案确实只是在this函数内将$(this)更改为bindUi。这肯定会奏效,但有两个“误解”:

  • 如果通过.locationSearch('bindUi')调用该函数,则this已经是jQuery对象,并且调用$(this)是多余的。
  • 如果您通过each中的init循环调用该函数,则this将引用 一个 DOM元素。因此,调用$(this)是必要的,但使用each循环一个元素是没有意义的。

  

如果我的每个方法都需要使用return this.each(function() { ..或只有initdestroy方法使用它,我也有点困惑?

每个应通过.locationSearch(method)调用的方法都应return this

答案 1 :(得分:3)

尝试$(this).each(

jQuery通常允许您使用this来引用纯HTML元素(而不是jQuery包装的元素)。你必须再次包装它以获得jQuery功能。