jQuery Code Does not have to be Ugly
I never pass up a chance to look at jQuery code. It’s amazing so much power can come from such a tiny package.
An appealing feature of jQuery is the browser independence it provides. Every JavaScript book I’ve read, includes code for checking which version, of which browser, the code is running in. There are a lot of: if else—if else—if else….statements. What a nightmare. No thanks. jQuery to the rescue!
However, most of the jQuery code I’ve seen uses anonymous functions even when they aren’t needed which makes the code harder to read, buggier and less maintainable. What a nightmare. No thanks. Note: I’m not anti-anonymous-functions; As a matter of fact, I use them in the code below (where appropriate).
Here’s a jQuery sample:
$(document).ready(function(){
$("Input.DataEntry").each(function(){if (this.value == "")this.style.backgroundColor = "yellow";else
this.style.backgroundColor = "White";});});
Putting that sample together took more than a few tries. While it looks trivial, getting the curly braces and parenthesis to match up took some iterative trial and error. Also, the debugger does not allow you to step into the code as it is written: Instead, the debugger steps into the jQuery source code. Yikes!
Here’s a cleaner way to connect a function to a jQuery event (Hint: don’t use an anonymous function):
$(document).ready(DocReady);function DocReady()
{ColorCodeTextBoxes();}
It is obvious what is being done in the code above…no problems with nesting curly braces and parenthesis. When the document is ready, the DocReady function is called. Let’s add a bit more code to show the advantages of doing it this way:
// ---- Main Doc Ready function -----------------
$(document).ready(DocReady);function DocReady()
{AssignClickToToggleButtons();ColorCodeTextBoxes();}// ---- ColorCodeTextBoxes -----------------------
//
// If a DataEntry textbox is empty, color it yellow
// otherwise color it white.
// To Do: use CSS classes instead of hard-coded color
function ColorCodeTextBoxes()
{var TextBoxes = $(":text.DataEntry");TextBoxes.each(function()
{if (this.value == "")this.style.backgroundColor = "yellow";else
this.style.backgroundColor = "White";});}
// ---- AssignClickToToggleButtons -----------------------
//
// add function to Toggle buttons click event.
// the function toggles the button's color with each click
function AssignClickToToggleButtons()
{$(".ToggleButton").click (function(){$(this).toggleClass('RedBackground').toggleClass('GrayBackground');})}
Hooking up a standalone function to an event is better than jamming the contents of the function into the event as an anonymous function. Here are some reasons why:
- The function can be assigned to other events*.
- The function can be debugged as a standalone object.
- The function can be better commented.
- The function can easily be removed, i.e.: // ColorCodeTextBoxs();
*In our example, you would want to Color Code the textboxes when the form loads and when it fails to submit to indicate which fields have been left blank.
Some may point out that by chaining results and nesting functions you avoid intermediate variables. To those people I give the Programmer’s Curse: “Someday, I hope you have to maintain your own code.”
Note that intermediate variables are absolutely mandatory when you are debugging: If you want to watch an object, you have to have something to watch.
I do concede that intermediate variables and non-nested functions may make the code run a few nanoseconds slower.
However, let me point out that just as real-estate agents have the phrase, “Location, Location, Location,” developers should adopt the phrase, “Maintenance, Maintenance, Maintenance.”
I hope someone finds this useful.
Steve Wellens