Плагин jQuery 'this.each не является функцией' - PullRequest
2 голосов
/ 26 февраля 2011

Я пытаюсь создать свой первый плагин 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 ]

4 голосов
/ 26 февраля 2011

Вы должны вызвать

methods.bundUi.apply(this);

в вашем методе init.

Если вы только выполните methods.bindUi(), то this внутри bindUi будет относиться к methods объект.

Обновление:

О, я только что видел это.Вы звоните methods.bindUi() внутри each.Тогда this будет ссылаться на текущий элемент DOM .Итак, вопрос в том, на что вы хотите сослаться внутри bindUi?Все выбранные элементы или только текущий элемент из цикла?

Вот два варианта:

A: Все элементы

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: один элемент .this внутри цикла each в 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() { .. или если его используют только методы init и destroy?

Каждый метод, который должен вызываться через .locationSearch(method), должен return this.

3 голосов
/ 26 февраля 2011

Попробуйте $(this).each(.

jQuery обычно позволяет использовать this для ссылки на чистый HTML-элемент (а не на jQuery).Вы должны снова обернуть его, чтобы получить функциональность jQuery.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...