image
Blog Post • development

Adding Functions to jQuery

May 21, 2009by Kevin Herrington 3 min read
Blog Post • development
Adding Functions to jQuery
Back to top

jQuery comes with a lot of functionality right out of the box, and even more in the form of plugins, but sometimes you run into situations where the function you want doesn't exist. Or maybe you just want to create a shortcut for a set of functions you use often. Maybe you even want to write your own jQuery plugin, but you aren't sure where to begin. For these situations, jQuery comes with a handy shortcut for adding functions, jQuery.fn.

Usage: jQuery.fn.yourFunction = function() { 
    // function logic 
}  
$('div').yourFunction()

I'll jump into an example. Let's say I'm using jQuery to round the corners of every div on the page. In this example, I'm laying a white quarter-circle over each corner as an easy way to round the box (when it's against a white background). This is fairly easy to do on its own. On document ready, I just find every div and add four corner divs inside of it. CSS will handle their positioning.

$(document).ready(function() {     
/* Round corners */ 
    $('#container div') 
        .css('position', 'relative') 
        .append( $('<div>').addClass('cornerTopRight') ) 
        .append( $('<div>').addClass('cornerTopLeft') ) 
        .append( $('<div>').addClass('cornerBottomRight') ) 
        .append( $('<div>').addClass('cornerBottomLeft') ); 
});

So the corner divs are created and the boxes are rounded. Perfect. But notice that this only runs on document ready. What happens if I make an AJAX call and create a new element based on the response data? Or what if I want to create a new div when an error occurs to give the user a warning? Those elements weren't on the page when the document first finished loading, so they won't be affected by my rounding script.

/* When New Div button is clicked, add a new div. */ 
$('input#new_div_button').click(function() { 
    $('<div>') 
        .text('Lorem ipsum dolor sit amet') 
        .appendTo('#container'); 
});

I could apply the same functions each time I create a new div, but counting the AJAX elements, warning divs and initial elements, I already have to copy this code three times in my source. Plus, if I ever want to change it, I have to change the same thing in several places. Awful solution. This is where jQuery.fn saves the day.

jQuery.fn.roundCorners = function() { 
    $(this).each(function() { 
        $(this) 
            .css('position', 'relative'); 
            .append($('<div>').addClass('cornerTopRight')) 
            .append($('<div>').addClass('cornerTopLeft')) 
            .append($('<div>').addClass('cornerBottomRight')) 
            .append($('<div>').addClass('cornerBottomLeft')); 
        }); 
    return $(this); 
} 
$(document).ready(function() { 
    $('#container div').roundCorners(); 
});

I've moved the round corners code into its own function $().roundCorners() by setting the function to jQuery.fn.roundCorners. There are a few important points to notice here. When you use a jQuery selector, it can return multiple elements to work with (i.e. $('div') usually matches several divs on the page), so I wrap the body of the function in $(this).each() to be sure every match is affected how I need it to be. Also, at the end, I return $(this), which is to say I pass the original element out after I'm done with it. The reason you can chain together jQuery functions (like $('#full-img').addClass('fading').fadeOut().fadeIn().removeClass('fading');) is that every function in the chain returns the object passed into it. There are some cases when you'll want to return other information, for example $(element).width() would probably return a number.

Anyway, I now have a function roundCorners() that I can call on any object (or set of objects) at any time. If I want to change the function, I only have to do it in one place and it takes effect everywhere. When I create new elements, I just have to add one more function to the chain to get what I want.

/* When New Div button is clicked, add a new div. */ 
$('input#new_div_button').click(function() { 
    $('<div>') 
        .text('Lorem ipsum dolor sit amet') 
        .roundCorners() 
        .appendTo('#container'); });

Authored by