jQuery Plugin Authoring – Step by Step

.

If you interested in JavaScript and jQuery plugin development then this one is for you(who have at-least jQuery plugin usage)

.

1. Add a new function property to the jQuery.fn object:

jQuery.fn.myPlugin = function() {

// plugin goes here

};

jQuery.fn is shortcut form of jQuery.prototype

2. Wrap up it with a self executing closure.

(function( $ ){
$.fn.myPlugin = function() {

// plugin goes here

};
})( jQuery );

$ in place of jQuery
it’s a best practice to pass jQuery to a self executing function (closure) that maps it to the dollar sign
so it can’t be overwritten by another library in the scope of its execution.

3. In the immediate scope of the plugin function, the this keyword refers to the jQuery object the plugin was invoked on.

(function( $ ){
$.fn.myPlugin = function() {

this.hide(); //the this keyword is the jQuery object of the DOM element on which you are pluging-in

};
})( jQuery );

4. jQuery selector query can match zero, one or more elements. This scenarios need to be considered when designing plugin

$.fn.myPlugin = function() {

this.each(function(){
//each() provides implicit iteration
});

};

5. Method chaining are a required behavior. Most cases We need to return a jQuery object from all plugin methods.

$.fn.myPlugin = function() {

return this.each(function(){
var $this = $(this);//have the jQuery object of the invoked element cahced for further use

});

};
With this we can chain our plugin method with built-in methods like

$('div').myPlugin().css('color', 'red');

6. Make your plugin configurable and put some default options too

$.fn.myPlugin = function(options) {

var defaults = {
 speed: 30, //some test data options here
 duration: 2000,
 frequency: 10000,
 //.....
 spread: 3
 }; //default options

//inherit from provided configuration (if any)
var options = $.extend(defaults, options);

return this.each(function(){

    var $this = $(this);
    //more stuffs goes here
});
};

7. Add some more functions

$.fn.myPlugin = function(options) {

var defaults = {
 speed: 30,
 duration: 2000,
 frequency: 10000,
 //.......
 spread: 3
 }; //default options

//inherit from provided configuration
var options = $.extend(defaults, options);

return this.each(function(){

    var $this = $(this);

    //some more functions added here
    var function1 = function(){};
    var function2 = function(){};

   function1(); //call functions to perform

});

};
8. Namespacing

Properly Namspacing your plugin assures that your plugin will have a very low chance of being overwritten by other plugins or code living on the same page.

9. Documentation
In-file documentation should be prepended to each function or method definition in proper format.

10. Example plugin:

A demo “Shake an Element” plugin created for more understanding of jQuery plugin structure which can be download from here :)

11. Usage

All plugin files must be named jQuery.myPlugin.js where myPlugin is the name of the plug-in.

Append your jQuery.myPlugin.js at the head section of your HTML Document.

<head>
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="jQuery.myPlugin.js"></script>
<script>
$(document).ready(function($) {
$('selctorQuery').myPlugin({speed:10,duration:3000,..spread:5});
});

</script>
</head>
12. Optional but useful :)

Compress and Minify your plugin codes

Packer

This JavaScript compressor/obfuscator by Dean Edwards is used to compress the jQuery source code. It’s available as a web-based tool or as a free download. The resulting code is very efficient in file size, at a cost of a small increase in execution time:

http://dean.edwards.name/packer/

http://dean.edwards.name/download/#packer

JSMin

Created by Douglas Crockford, JSMin is a filter that removes comments and unnecessary white space from JavaScript files. It typically reduces file size by half, resulting in faster downloads:

http://www.crockford.com/javascript/jsmin.html

JavaScript Object Literal Namespacing

JavaScript Object Literal is a comma separated list of name-value pairs enclosed within a curly braces, means of encapsulating lots of data under a namespace, where the name is a valid variable name and the name can be used as variable. Values can be of any data type, including array literal and object literal.

Purposes of JavaScript Object Literal notion:

  • It provides encapsulation
  • Avoiding global namespace pollution
  • Relatively straightforward to implement

A namespace is a context for identifiers, simply a namespace is an abstract container for items such as names, objects etc. Also within a namespace, the components can not share the same name.

Encapsulation, In his influential book on object-oriented design, Grady Booch defined encapsulation as “the process of compartmentalizing the elements of an abstraction that constitute its structure and behavior; encapsulation serves to separate the contractual interface of an abstraction and its implementation.”

An example given as:

/*
* BlogPost : creating BlogPost object using object literal notation
* basic structure: {name:value, name:value};
* or can be as { name:value, { name:function(){...},...}, name:value ... }
*/
var BlogPost = {

 title: 'Welcome to My Blog',  // Blog title
 numberOfView: 0,    // Number of Blog view
 blogContent: '',    // Blog post content
 URL: 'http://mahtonu.wordpress.com', // Blog post URL
 flag: false,        // Use some flag
 lastView: null,     // Timestamp of the last Blog view

 //set blog content here
 setContent: function(content) {
 this.blogContent = content;
 },
 //get blog content
 getContent: function() {
 return this.blogContent;
 },
 //count the number of blog post view
 incrementView: function() {
 this.numberOfView++;
 },
 //set timestamp of the last Blog view
 setTimeStamp: function(time) {
 this.lastView = time;
 },
 //get timestamp of the last Blog view
 getTimeStamp: function() {
 return this.lastView;
 },
 //get blog url
 getBlogUrl: function() {
 return this.URL;
 }
};

In the avobe example the  “BlogPost” object created using object literal notion with some properties. Thus the property values can be manipulated using methods sharing the namespace. Further adding property or methods are simple enough.

More usage:

//set some post here
BlogPost.setContent('I am a body of a blog post!');
BlogPost.setTimeStamp('14th April 2010 09.00PM');
//publish your blog post
document.write('Title: '+BlogPost.title);
document.write('Post: '+BlogPost.getContent());
document.write('Link: '+BlogPost.getBlogUrl());
document.write('Posted at: '+BlogPost.getTimeStamp());
document.write('Total Viewed: '+BlogPost.numberOfView);
//got a hit increment your view no
BlogPost.incrementView();

So we are accessing and working around the properties of an object forming a namespace.

References /Further Readings:

Wiki page for Information hiding [Encapsulation Part]

Tim McCormack on Javascript object literal namespacing

Jonathan Snook on Objectifying JavaScript

Good JavaScript Study Resources

:)

Rules, Naming , Conventions

Google JavaScript Style Guide

JavaScript: The World’s Most Misunderstood Programming Language by Douglas Crockford (2001)

http://javascript.crockford.com/javascript.html

“Private Members in JavaScript” by Douglas Crockford (2001)

http://www.crockford.com/javascript/private.html

Code Conventions for the JavaScript Programming Language

http://javascript.crockford.com/code.html

ECMA-262-3 in detail

http://dmitrysoshnikov.com/

OOP: The general theory.

http://dmitrysoshnikov.com/ecmascript/chapter-7-1-oop-general-theory/

Object Oriented Programming in JavaScript

http://mckoss.com/jscript/object.htm

.