July 01, 2010Write comment

How to create your own jQuery plugin from scratch

Firstly, wouldn’t it be nice to have a plugin that, whenever you hover an element, applies some sort of styling to it? Ok, the answer I was expecting here is “yes”.

Starting out

As we all know, the basic structure for a plugin is

jQuery.fn.pluginName = function () {
	return this.each (function () {
		// code
	});
}

Mind the ‘jQuery’ part (not just ‘$’) so aliases can be easily set using the noConflict() method.

And this would be enough to paint an element blue with some yellow text

jQuery.fn.paint = function () {
	return this.each (function () {
		$(this).css ("color", "yellow").css ("background-color", "blue");
	});
}

We should now have two files ready: one is the HTML page, from which the jQuery library is included; the other is the plugin.js file, containing the above snippet. The plugin file must be included in the page too, just after the jQuery script!

Inside the $document).ready() function goes the following

$(document).ready (function () {
	$("#mydiv").paint ();
})

Make sure, of course, you have a div element called ‘mydiv’ with something written in!

Now check and see the yellow text on blue background.

One step further

Fine. That’s nice. But we want the plugin to work for every element without having to change colors every time.

Back to plugin.js, we change our plugin definition to accept options.


jQuery.fn.paint = function (options) {
	var defaults = {
		fg: 'yellow',
		bg: 'blue'
	};

	var opts = jQuery.extend (defaults, options);

	return this.each (function () {
		$(this).css ("color", opts.fg).css ("background-color", opts.bg);
	});
}

The ‘defaults’ object is to hold the values we want to back off to when they are not passed with the options parameter.

The very next part (jQuery.extend) tells the library to combine the two objects: if some of the options are not passed by the user, we use the defaults; the ‘opts’ object is what we’ll be using from now on to access those variables.

To check this step, reload the page, seeing no changes (we haven’t passed any arguments, so we default to yellow text on blue background).

Though, if we had two elements

<div id="first">Hello there</div>
<div id="second">I'm cool</div>

we could color those two in different ways with our shiny new plugin

$("#first").paint ({ fg: 'blue', bg: 'yellow' });
$("#second").paint ({ fg: 'red', bg: 'green' });

Not bad huh?

Hovering effect

We’re now facing another problem though: our first intention was to activate this behavior when hovering the element, not once the page loads and forever!

Nothing easier! We use this code to activate the effect

$(this).hover (function () {
	$(this).css ("color", opts.fg).css ("background-color", opts.bg);
});

But we have to find a way to remember the previous colors and restore them once the mouse moves out.

return this.each (function () {
	var obj = $(this);

	var fg_old = obj.css ("color");
	var bg_old = obj.css ("background-color");

	obj.hover (function () {
		obj.css ("color", opts.fg).css ("background-color", opts.bg);
	}, function () {
		obj.css ("color", fg_old).css ("background-color", bg_old);
	});
});

This should be pretty straightforward, anyway:

  • we store the current colors in some variables
  • then hovering, paint the element with the colors passed by the user
  • the second parameter of the ‘hover’ function describes what to do when the mouse moves out: just revert to the original color combination.
  • NOTE we haven’t called ‘$(this)’ hundreds of times; just once to assign the object to a variable to make the whole script faster.

That’s it, our plugin is built. We can focus on soe improvement now.

Closures

An interesting thing to know and understand is closures.

Closures make it possible for the developer to create functions in the main namespace and keep them private (can be used by your plugin only) to avoid cluttering and backward compatibility.

We could then add a completely useless function to see how this all works.

(function($) {
	jQuery.fn.paint = function (options) {
		var defaults = {
			fg: 'yellow',
			bg: 'blue'
		};

		var opts = jQuery.extend (defaults, options);

		return this.each (function () {
			var obj = $(this);

			var fg_old = obj.css ("color");
			var bg_old = obj.css ("background-color");

			obj.hover (function () {
				obj.css ("color", opts.fg).css ("background-color", opts.bg);
				showMessage (obj);
			}, function () {
				obj.css ("color", fg_old).css ("background-color", bg_old);
			});
		});
	};

	function showMessage ($obj) {
		alert ($obj.html ());
	};
})(jQuery)

The newly added function ‘showMessage’ is only visible within the closures and, in this case, can only be accessed by our plugin methods.

Final thoughts

And here we are, with our simple yet nice plugin you can expand and improve adding support for many other third party plugins that offer this possibility.

You can download the final result from here.

See also

Post a comment and tell the world what you think of this super awesome page!
  1. No comments yet.

  1. No trackbacks yet.

Parents told me to avoid people I don't know.
No spam, I promise. And not published either!
Free do-follow link to your website.