MaxSide: jQuery Plugin (and How-To)

Avatar of Chris Coyier
Chris Coyier on (Updated on )

Abstraction is an important concept in any language. You can think of CSS as a way of abstracting the design away from the content of a site. This makes the code for both much easier to read, understand and maintain. Javascript is a way of abstracting away the functionality of a site, and jQuery a further abstraction making common tasks much much easier. Writing plugins for jQuery is yet another deeper abstraction which makes your jQuery easier to write and understand.

To illustrate this idea, let’s build an jQuery plugin. While we’re at it, it might as well be something useful! We’re going to call it MaxSide. The idea here is to take any page element and resize it, making the length of its longest side a value you determine. For example, if you have an image that is 300x180px you could call MaxSide on it with a value of 100 and the resulting image would be 100x60px (it maintains its ratio).

Let’s get to it.

 

Doing it Without a Plugin

Let’s put three images on the page, one 200x200px, one 200x50px, and one 50x200px.

<body>
	<img src="images/200x200.jpg" alt="" />
	<img src="images/200x50.jpg" alt="" />
	<img src="images/50x200.jpg" alt="" />
</body>

We want to run some jQuery on these images so that each of their longest sides becomes 100. 200x200px becomes 100x100px, 200x50px becomes 100x25px, and 50x200px becomes 25x100px.

Let’s include jQuery on our page (in the <head> section) and write the code that will make this happen:

<script type="text/javascript" src="../jquery-1.2.6.min.js"></script>

<script type="text/javascript">

	// don't run until all images are loaded
	$(window).bind("load", function() {
	
			// run on every image on the page
			$("img").each(function(){
				
				// set a variable for this, quicker
				var $this = $(this);
				
				// maximum length is hard-coded here
				var $maximum = 100;
				
				// jQuery 1.2.6 has "dimensions" built-in
				var $thewidth = $(this).width();
				var $theheight = $(this).height();

				if ($thewidth >= $theheight) {
					if ($thewidth >= $maximum) {
						$(this).attr({
							width: $maximum
						});
					}
				}

				if ($theheight >= $thewidth) {
					if ($theheight >= $maximum) {
						$(this).attr({
							height: $maximum
						});
					}
				}                   
			});
		});
</script>

In plain English, this reads: “Look at every image on the page. If it is wider than it is tall, make it’s width 100. If it’s taller than it is wide, make it’s height 100.”

Works like a charm, see the example without the plugin.

 

Doing it With a Plugin

There are a couple of problems with doing the “without the plugin” way. For one, it really dirties up our page. We should really get all that code off of our HTML file, as that is where our content lives and we are trying to abstract here. Two, the “MaxSide” is hard-coded here. What if we want to use this same bit on the page but use a different MaxSide value. We would have to repeat very similar code. Never a good idea.

jQuery makes it easy for us to write our own functions in the form of plugins, to abstract away code like this. Take a look at the new code in our header, using the plugin:

<script type="text/javascript" src="jquery-1.2.6.min.js"></script>
<script type="text/javascript" src="jquery.maxside.js"></script>
<script type="text/javascript">
	$(window).bind("load", function() {
		$("img").maxSide({ maxSide: "100" });
	});
</script>

A lot simpler, eh? But not only simpler, but now we could call the maxSide function on different page elements and with different values to boot.

jQuery.fn.maxSide = function(settings) {
		// if no paramaters supplied...
		settings = jQuery.extend({
			maxSide: 100
		}, settings);		
		return this.each(function(){
				var maximum = settings.maxSide;
				var thing = jQuery(this);
				var thewidth = thing.width();
	            var theheight = thing.height();
	
				if (thewidth >= theheight) {
	                if (thewidth >= maximum) {
	                    thing.attr({
	                        width: maximum
	                    });
	                }
	            }

	            if (theheight >= thewidth) {
	                if (theheight >= maximum) {
	                    thing.attr({
	                        height: maximum
	                    });
	                }
	            }
		});	
};

Notice the code really isn’t all that different here. There are a couple of important things to note though.

  • This plugin is built to do its thing on every page element that matches what you call it on. Hence the “each” function. If you wish to write a plugin which only effects a single page element, it is even easier. Omit the “each” function and write regular ol’ jQuery but include a “return this;” line at the end.
  • The “settings” bit at the beginning of the function handles the event in which the function is given no parameter (it defaults to 100px). You could technically call this function with just .maxSide(); if you wanted.
  • If you are using this function on images, it should only be called after the window load event. Many jQuery functions are called when the DOM is ready instead, which is much faster, but the width and height calculations will fail if the images are not fully loaded yet (very probable).
  • Variables inside the plugin don’t need the “$”.

View Demo Download Example