简体   繁体   中英

Calling member function inside of Jquery Plugin

I have created a basic plugin template based on the code generated here: http://starter.pixelgraphics.us/

Here is a link to the very basic skeleton: https://jsbin.com/yatofefade/edit?html,js,console,output

 $.curationPanel = function( el, options ) { var base = this; base.$el = $(el); base.el = el; base.$el.data( "curationPanel", base ); base.init = function( ) { base.options = $.extend( {}, $.curationPanel.defaultOptions, options ); }; base.runMe = function( ) { alert( "I've Been Run" ); }; base.init( ); }; $.curationPanel.defaultOptions = { }; $.fn.curationPanel = function( options ) { return this.each( function( ) { (new $.curationPanel( this, options )); }); }; $(".curationPanel").each( function( i, val ) { var cp = $(this).curationPanel({}); cp.runMe( ); }); 
 <!DOCTYPE html> <html> <head> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <meta charset="utf-8"> <meta name="viewport" content="width=device-width"> <title>JS Bin</title> </head> <body> <div class="curationPanel">INSIDE THE PANEL<div class="curationErrors"></div></div> </body> </html> 

My question is, why do I get an error when trying to call runMe( ) on a created instance of curationPanel? What is the correct way to create callable public functions within the plugin?

In your case cp is a jQuery object, not an instance of the curationPanel since you are returning this from the plugin method, that is why the error.

There are multiple ways to do this.

One way is to break the chaining nature of the jQuery and return an instance of the plugin object as shown below. Other than breaking the chaining nature of jQuery method, another drawback of this design is, at any call you can use this to initialize the plugin for only one element, ie if you have a selector which selects more than 1 element and then call the plugin, the plugin will be initialized for only the first element.

 $.curationPanel = function(el, options) { var base = this; base.$el = $(el); base.el = el; base.$el.data("curationPanel", base); base.init = function() { base.options = $.extend({}, $.curationPanel.defaultOptions, options); }; base.runMe = function() { snippet.log("I've Been Run"); }; base.init(); }; $.curationPanel.defaultOptions = {}; $.fn.curationPanel = function(options) { return new $.curationPanel(this[0], options); }; $(".curationPanel").each(function(i, val) { var cp = $(this).curationPanel({}); cp.runMe(); }); 
 <!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> <script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="curationPanel">INSIDE THE PANEL <div class="curationErrors"></div> </div> 


Another way is to obtain the plugin instance using the data api like

 $.curationPanel = function(el, options) { var base = this; base.$el = $(el); base.el = el; base.$el.data("curationPanel", base); base.init = function() { base.options = $.extend({}, $.curationPanel.defaultOptions, options); }; base.runMe = function() { snippet.log("I've Been Run"); }; base.init(); }; $.curationPanel.defaultOptions = {}; $.fn.curationPanel = function(options) { return this.each(function() { (new $.curationPanel(this, options)); }); }; $(".curationPanel").each(function(i, val) { var cp = $(this).curationPanel({}); $(this).data('curationPanel').runMe(); }); 
 <!-- Provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 --> <script src="http://tjcrowder.github.io/simple-snippets-console/snippet.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <div class="curationPanel">INSIDE THE PANEL <div class="curationErrors"></div> </div> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM