Automatically Wiring Up XHTML Element Events On Page Load With jQuery

Many Web developers find themselves in an environment where the design of a Web page is handled by a graphic designer or junior programmer, either as part of their team or from a subcontractor or the client himself.

Unfortunately, traditional HTML / XHTML requires most element events handlers — onmouseover, onclick, onfocus, etc. — to be coded as attributes of the tag, like this:

<img id="myimage" src="pic1.jpg" alt="My Image" onmouseover="this.src='pic2.jpg'" onmouseout="this.src='pic1.jpg'" />

That’s not a problem if you’re the end point of the code; that is, if the graphic designer hands you a final page that won’t be modified again. But in the real world, pages and their associated code need to be moved back and forth constantly, with changes aplenty. That can have a real impact on your work, especially if the designer changes or removes your event handlers from page elements.

That’s the idea behind MVC (model, view, controller). We break the chain of custody for a Web request into three parts: A controller accepts a request from the user and determines which model should be used to handle the request.

The selected model, in turn, does something with the request sent to it by the controller; for example, one model might serve up some static content; another model returns search query results; another model returns data based on an environment variable, such as the geolocation of the user’s IP address (that is, gives a page in Russian to a user from Russia, by default); and so on.

Finally, the view — the end output the user sees — is applied by the controller to the model’s results.

While this is a worthwhile development approach, it may be a bit of overkill for a site that doesn’t have too much dynamic content, or that simply needs an image rollover effect, a countdown clock, etc. We still want to protect our coding from alteration by the designer, but we don’t want to employ a $10 solution to a 10-cent problem.

Enter, once again, jQuery, which can automatically bind (that is, “wire up”) event handlers for us once the page loads.

$(document).ready() To The Rescue

The jQuery library includes a class named document (a half-brother of JavaScript’s document class) and a method of that class called ready(). This fundamentally acts the same as the onload event handler of either the window or body HTML DOM objects in JavaScript — except that $(document).ready() does not require us to hard-code it into an DOM element.

As always, we start by downloading the latest version of jQuery, if we haven’t already done so, and adding a reference to it on our page.

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

To wire up an event for a single tag, we simply call $(document).ready(), reference the element we want into a jQuery Element object, then bind the event handler we want to use.

You’ll note in the jQuery documentation that there are several different ways to bind an event to an element. I’m going to use the most direct method: namely, calling the appropriate event property of the element and assigning a function that way.

Let’s use the example of an image rollover. Assume we have the following HTML for the image:

<img id="myimage" src="out.jpg" alt="my image" />

Let’s suppose the rollover image is named over.jpg. Let’s add — “wire up” — onmouseover and onmouseout event handlers:

$(document).ready(function () {
	$("#myimage").mouseover(function() {
		$("#myimage").attr("src", "over.jpg");
	});
	$("#myimage").mouseout(function() {
		$("#myimage").attr("src", "out.jpg");
	});
});

What if we want to wire up several event handlers? We certainly can do so by coding them individually, as we do above. But we can also wire up the same event handler to all the same elements, elements in the same class, elements with the same attribute, alternating elements, child or sibling elements, etc. — pretty much any relationship or similarity can be accounted for.

Suppose we want to pop up an alert box, any time a checkbox is checked, with the value of that checkbox:

$(document).ready(function () {
	$("input[type='checkbox']").click(function() {
		alert("You just clicked the " + $(this).val() + " checkbox!");
	});
});

Or maybe, we want to change the background color of all alternate table rows; change the color of a row when we mouse over it; and change the color of a row when we click on it:

$(document).ready(function () {
	$("tr:even").addClass("row-alt");
	$("td").mouseover(function() {
		$(this).parent().addClass("row-over");
	});
	$("td").mouseout(function() {
		$(this).parent().removeClass("row-over");
	});
	$("td").click(function() {
		$(this).parent().toggleClass("row-click");
	});
});
.row-alt {
	background-color: #eee;
}

.row-over {
	background-color: #ffc;
}

.row-click {
	background-color: #fc9;
}

You can see all of these in effect here: http://demo.dougv.com/jquery_event_wireup/

I distribute code under the GNU GPL version 3.

Hopefully, this gives you an idea of the power of jQuery, and its ability to help you adopt object-oriented concepts, such as modularity and abstraction, in your traditional Web projects.

2 Comments

Leave a Reply

  • Check out the Commenting Guidelines before commenting, please!
  • Want to share code? Please put it into a GitHub Gist, CodePen or pastebin and link to that in your comment.
  • Just have a line or two of markup? Wrap them in an appropriate SyntaxHighlighter Evolved shortcode for your programming language, please!