Patterns In Jquery Plugin writing
Well, there is nothing new to write about how to write a jquery plugin, there are a lots of articles available on the web including jquery site and those are more than enough to learn about writing a jquery plugin. So I’m not going to teach anything new today but instead, I’m trying to discuss about various ways and difference of writing a jquery plugin that developers use, because everyone doesn’t use the same pattern and sometimes it creates confusions.
Pattern-1:
(function( $ ) { $.fn.myPlugin = function() { // plugin stuff here }; })(jQuery);
Pattern-2:
(function( $ ) { $.fn.extend({ x: function() {}, y: function() {} }); })(jQuery);
What is the difference ?
Ultimately nothing. Both patterns are correct. The first pattern is the simple way of adding an attribute to an object. In javascript, you can add an attribute to a custom object like this. Here the fn is an object and myplugin is a new attribute/method and the function right side of the = is an anonymous function assigned to this method. Now lets see an example how to do it in javascript.
// Create an object function myObj() { this.attribute1='some value', this.attribute2=function(){ alert("ok"); } } var obj1=new myObj(); alert(obj1.attribute1); // Will alert 'some value' obj1.attribute2(); // will alert 'ok'
Now, if we want to add a new attribute to our myObj then we could do that in the following way.
myObj.prototype.attribute3=function(){ alert('new method'); } obj1.attribute3(); // will alert 'new method'
Here, in our first pattern we did the same thing. The fn is an object (an alias of prototype) and we’ve just added a new attribute to it and the anonymous function is it’s value, so, you can say that, we’ve extended it or added a new method to fn object and named it myPlugin. Now, if we write $(‘some_element’).myPlugin(), the anonymous function at the right side of ‘=’ in our plugin, will be executed. In the second pattern, same thing happened but using jquery’s extend method, instead. In this case, we’ve extended the fn object and added two new items to it using javascript object literal. The benefits of using this pattern is that, we can add multiple items/plugins in the same time as we did here, x and y become now two new plugins and these belongs to fn object. That’s it. Hope I could make it clear.
Important:
To maintain the chainability the ‘return’ keyword has to be used with ‘this’ keyword and use jquery’s ‘each’ method inside your plugin to apply some action to a collection of matched elements. Lets see.
(function( $ ) { $.fn.myPlugin = function() { return this.each(function() { // plugin stuff here }); }; })(jQuery);
If we call $(‘div’).myPlugin().css(‘color’,’black’), all the div will be effected by our plugin because we wrote the function inside each (plugin will loop all divs) and after the plugin’s operation .css() will change the text color of all divs because we’ve returned the object using ‘return’ keyword, if we didn’t then we had to call the .css method seperately like this
$('div').myPlugin(); $('div').css('color','black');
Passing arguments to the plugin
// pattern-1 (function( $ ) { $.fn.myPlugin = function(options) { var settings={ 'background_color':'gray', 'foreground_color':'black' }; $.extend( settings, options ); return this.each(function() { // plugin stuff here $(this).css({ 'background':settings.background_color, 'color':settings.foreground_color }); }); }; })(jQuery); // pattern-2 (function( $ ) { $.fn.extend({ myPlugin: function(options) { var settings={ 'background_color':'gray', 'foreground_color':'white' }; $.extend( settings, options ); return this.each(function() { // plugin stuff here $(this).css({ 'background':settings.background_color, 'color':settings.foreground_color }); }); } }); })(jQuery);
Now we can call our plugin with options/parameters like this
$('div').myPlugin({ 'background_color':'#fff', 'foreground_color':'gray' }); //or just simply without any arguments $('div').myPlugin();
In the plugin above we’ve created an object(settings) and gave some default options ‘background_color’:’gray’ and ‘foreground_color’:’black’ and merged it with user’s options, using $.extend( settings, options ), so if we call the plugin without any parameter/option, by default, values of the ‘defaults’ object will be applied, that means, background-color will be gray and color will be black. If we want to change only background color then we can call it with one argument as, $(‘div’).myPlugin({‘background_color’:’white’}). That’s it.