0

Plugin:

(function( $ ){

  $.fn.myplugin = function( options ) {  

    var mymethod = function(){
      // I want to be able to access "this" here ('.element')

      return this; 
    };

    return this.each(function() {        
      // $('.element', this).mymethod(); <- how to do this?
    });

  };
})( jQuery );

I want to call mymethod like this:

$('.element').mymethod();

Is this possible?

Basically it needs to keep the chaining so I can further call other functions...

1
  • You could get rid of the wrapping function and simply assign to jQuery.fn.myplugin (unless you want to be able to use the $ alias elsewhere). Commented Jan 23, 2012 at 0:01

5 Answers 5

2

If you haven't already done so, I would highly recommend checking out the jQuery plugin authoring page. http://docs.jquery.com/Plugins/Authoring

The best way to call a specific method would be by going

$( '#foo' ).myPlugin( 'myMethod' );

The way you would achieve something like that would be like this, ( note: all taken from the jQuery plugin authoring site )

( function ( $ ) {

    var methods = {
        init : function( options ) {

            // Init function here

        },
        destroy : function( ) {

            // Teardown function here

        }
    };

    $.fn.myPlugin= 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.myPlugin' );
}    


};

})( jQuery );
Sign up to request clarification or add additional context in comments.

Comments

2

If you want to call it like a jQuery plugin you will have no way around adding it to the jQuery prototype ($.fn). But if you just want to have this reference the jQuery element of your selector you can just use apply:

(function( $ ){

  $.fn.myplugin = function( options ) {  

    var mymethod = function(){
      // I want to be able to access "this" here ('.element')

      return this; 
    };

    return this.each(function() {        
      mymethod.apply($('.element', this));
    });

  };
})( jQuery );

Comments

2

Close, you just lose the this keyword whenever there's a new function keyword. Try saving it first:

(function( $ ){

  $.fn.myplugin = function( options ) {  

    var that = this;

    var mymethod = function(_this, dotElem){
      // I want to be able to access "this" here ('.element')
        that.hide().blah()...

      return this; // this isn't needed as we are going to anyway return `this.each()`
    };

    return this.each(function() {        
        mymethod(this, $('.element' )); <- how to do this?
    });

  };
})( jQuery );

Comments

1

Well, then you'd just do:

$.fn.mymethod = function () { ...   return this; }

jQuery will automatically pass the element it's called on as this.

But it's considered bad practice to add lots of functions this way. That's why most plugins just add one function to $.fn and take a string argument for which method to call.

1 Comment

that's why I want to keep the functions as variables, because I have quite a few..
1

Alter MyMethod so its a direct extension

$.fn.mymethod = function() {
   this.hide(); // the .element
   return this; // continue the daisy chain
}

// example usage
$(document).ready(function() {
   $("div").mymethod();
});

Updated x2 (had a typo)!

http://jsfiddle.net/MattLo/2TWMV/1/

3 Comments

updated with example. For every $.fn."methodName", its a direct extension to the jQuery methods, any return on new object literals are not part of the jQuery extension.
Within a jQuery method, this refers to the jQuery collection, not the underlying array of elements. So, the dollar signs in $.fn.mymethod are unnecessary. In fact, the function's body should simply read return this.hide().
you are correct, although I didn't want to return the daisy chain this.hide(); since I'm assuming if the goal is to make an extension, there's a bigger task at hand. Updated

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.