Coding, JavaScript / JQuery

JQuery Best Practices for Beginners

jQuery heavily relies on JavaScript (and is JavaScript) and CSS – so this article will also include some information and best-practices related to those as well.

The “var” keyword:
JavaScript is naturally a dynamic/weak-typed language, there is no notion of compile-time data types. Instead, JavaScript figures out the type at run-time and throws an exception if something is wrong. If you start to use a variable, it is considered to be a “globally” scoped variable – meaning it is available everywhere.

Instead, if you declare a variable with the var keyword, that makes that variable only valid to the current “scope” (curly braces, method, etc).

function doStuff() {
isEnabled = true;       // Global scope, available everywhere.
var isActive = true;    // Local scope, only available within doStuff()
}

Best-practice: use the “var” keyword often. All variables should be declared in the tightest scope possible.

CSS Types:
When declaring CSS types, there are 3 different types “selectors” that can be used, to select which items will subscribe to that current style:

#mainTable   /* Applies to any element that has an id="mainTable"           */
{ background-color: White; }
.header      /* Applies to any element that has a attribute  */
{ background-color: #7d7d7d; color: White; }
td a         /* Applies to all <td /> and <a /> elements                    */
{ font-size: 9pt; }

You can use #id to reference items that all have a specific id. For example, on several pages, you might have <div id=”helpLabel”>. Without having to add <div id=”helpLabel”> or something like that, you can just apply a style to #helpLabel.

Using a preceding dot is a standalone class that can be manually applied via the class=”” attribute on any HTML element. For example, <div class=”header”>Some text here</div> and <td class=”header”>Column A</td>

Lastly, you can set the defaults for a tag, for anywhere it appears. You do this by naming the CSS class after the name of the element – like h1, td, a, etc.

Best-practice: put CSS styles in an external .css file. Use ID-based or simple classes (with a “.” prefix) for most styles. Only stylize at the tag-level if you are sure it will definitely apply to every single instance. Use things like font-family and font-size at the tag level, use the other approaches for more specific decorations.

Which CSS style wins?
When you specify multiple CSS styles that directly conflict, the “closest one wins”. This means that closest definition to the element, wins. Considering that you can use style=”” attributes on an element, that is closest; having a <style> tag earlier in the page is next closest; an external .css is the furthest and will take least precendence.

Best-practice: put CSS in a seperate .css file and ideally move all in-line or <style> functionality there as well – so that the page has no on-page style information.

Referencing JavaScript:
Ideally, virtually all JavaScript should be put into external .js files, “minified” (white spaces taken out), and functions should be put into a namespace, for maintainability.

Best-practice: externalize code to .js files and minify them before going to production, for performance.

JavaScript Functions/Methods:
JavaScript and consequently jQuery use the notion of function pointers. This is an important distinction when calling a function:

function doStuff() {
return "hello";
}

var result1 = doStuff(); // Returns "hello"
var result2 = doStuff;   // Returns a function pointer to
// doStuff, and does NOT execute it!

One significant benefit is that you can pass functions as arguments into methods, and store function pointers into variables (like “result2”, above). This is significant, because jQuery leverages this ability, heavily.

JavaScript Anonymous Functions:
To take this idea one step further, you can create and run a function on-the-fly, without naming it first (doStuff, above is a “named function”). jQuery uses this idea heavily too. Below are a few different ways to do the same thing:

// OPTION 1: Use a Named function
function doStuff() {
return "hello";
}

document.write(doStuff());

// OPTION 2: Use a function pointer
var $doStuff = function () {
return "hello";
}

document.write($doStuff());

// OPTION 3: Use an anonymous function
document.write(function() {
return "hello";
});

Option 3 is perhaps more difficult to read if you are not familiar with anonymous functions, but it is the least amount of code – and definitely the most popular approach. Again, jQuery uses the “option 3” approach just about all of the time.

JavaScript ‘prototype’ keyword:
JavaScript is a weakly-typed language, but if you want to associate a method with a variable, there is a way to do this – with the prototype keyword. This means for a specific variable, tack on this method, which might make that JavaScript object easier to use. This is basically “extension methods” in C#, if you are familiar with that – same thing, except for JavaScript. For example:

var firstName = "Steve"
firstName.prototype.reverse = function () {
return this.split("").reverse().join("");
}

// We now have support for a .reverse() method, on firstName
var reversedName = firstName.reverse();

Best-practice: this can be difficult to maintain, consider using a namespace if you need this type of functionality.

JavaScript Namespaces/Object Literals:
A JavaScript “namespace” is yet another meaning of that word, that isn’t the same as any other meaning! A JavaScript namespace really feels like a static/shared “class” in other languages. It is a programming contruct to hold fields/properties and methods. For example:

var customer = {
firstName: "",
lastName: "",
fullName: function () { return firstName + " " + lastName; }
}

customer.firstName = "Sally";
var name = Customer.fullName();

Best-practice: If you must get this specific in JavaScript, this is perhaps the best way to organize your data. Ideally though, it would be best to work with server-provided data constructs, in JSON format. Put all custom variables and methods in a namespace with a meaningful name

jQuery Selectors “get something, do something”:
jQuery is build on this idea of “get something, do something” or, go find something on the page, and then do something to it. Therefore, the ability and the techniques use to “find something” should be pretty powerful. In jQuery, they are. With just JavaScript, you are stuck with using document.getElementById(..), but with jQuery, you can “find” or create things very easily. Below is some syntax and shortcuts for common ways to “find” things within the DOM:

$("*")                    // Select everything in the DOM
$("#first")               // Gets all elements that have an id="first" (e.g. <div id="first"/> <input id="first" />
$("div");                 // Gets all div elements
$(".pageTitle")           // Gets all elements with the pageTitle class (e.g. <div />)
$("*[width]");            // Gets all elements with a width attribute (e.g. <div width="80"/>)
$("img[width]")           // Gets all img tags that have a width attribute
$("div.pagetitle");       // Gets all div elements with pagetitle class (e.g. <div></div>)
$("div#intro .pagetitle") // Gets divs that have an id of intro, and within that, have classes of pageTitle
$("html > body input")    // Gets the HTML tag, then a direct descendant of body, then an input somewhere below
$("input:eq(1)")          // Gets all input tags, then select the second one (zero-based)
$("#yourId", ".myClass")  // Comma "unions" results of all jQuery selectors
$("ul > li:even")         // Gets all ul tags, then selects the even <li> items within

It is “expensive” to traverse the DOM, so if you need an element for more than one operation, put the results into a variable. For example:

// Lookup the element once
var $firstName = $("#firstName");

// Now reference it
$firstName.addClass("highlight");
$firstName.width("80px");

Best-practice: Use the most specific selector you can, with ID’s being the fastest and preferred way. If you are going to use a selector for more than one operation, put the reference in a variable so that you don’t have to re-find it for every additional operation.

jQuery Events:
You can wire up JavaScript events with things like <a id=”mainLink” href=”#’ onclick=”doSomething(); return false;”>test</a> – or you can do it via jQuery code, typically like this:

$("#mainLink").click(function(){
alert('Clicked');
});

Best-practice: avoid using the event definitions in the tags themselves. Instead, wire up all events via code.

$(document).ready() versus body.onLoad():
The body onLoad event occurs when the DOM has been loaded, and all content (images, flash, silverlight, etc) has loaded. This is good because you are sure the entire page is loaded, but it’s often unnecessary, because you only need to worry about the DOM being loaded.

$(document).ready() is an event that fires when the DOM has been loaded. The advantage here is that you know the actual structure of the page has been loaded, and you can start doing work. There are many, many ways to refer to this function, the preferred way is using $().ready(..). Even though you can just do $(func), having at least the .ready() helps make it more readable. For example:

$().ready(function () {
$("#mainLink").click(function () {
alert(this.id + ' was clicked');
});
});

Best-practice: unless there is a specific reason to use body onLoad, always use document.ready. Use the syntax: $().ready(..)

Copying, moving, wrapping, and clearing elements:
For most DOM manipulation operations, if you specify the results of an existing element, that element will be MOVED, not COPIED. Here is a summary of the main methods used for manipulation:

  • .after() inserts a string or element after the specified element (sibling).
  • .append() appends a string or element at the end of children, of the specified element (child).
  • .before() inserts a string or element before the specified element (sibling).
  • .empty() removes all children from an element, but leaves the element in the DOM
  • .prepend() inserts a string or element at the beginning of the children, of the specified element (child).
  • .remove() removes an element and all children from the DOM
  • .replaceAll()/.replaceWith() replaces an element with another element – or specified text.
  • .wrap() wraps a new outer element around EACH matching element.
  • .wrapAll() wraps ALL matching entries from the jQuery selector into one container.
  • .wrapInner() wraps the internal elements of EACH matching entry from the jQuery selector.

Given the following HTML, here are some examples:

<div id="firstDiv">First Div</div>
<div id="secondDiv">Second Div</div>
$().ready(function () {
var $firstDiv = $("#firstDiv");
var $secondDiv = $("#secondDiv");

$firstDiv.append($secondDiv);           // MOVES $secondDiv as a child WITHIN $firstDiv, at the
//   end of the list of children.
$firstDiv.prepend($secondDiv);          // MOVES $secondDiv as a child WITHIN $firstDiv, at the
//   beginning of the list of children.
$firstDiv.before($secondDiv);           // MOVES $secondDiv to be a sibling before $firstDiv.
$firstDiv.after($secondDiv);            // MOVES $secondDiv to be a sibling after $firstDiv.
$firstDiv.replaceAll($secondDiv);       // REPLACES $secondDiv with $firstDiv (move, not a copy
//   of $secondDiv)

$firstDiv.replaceWith(
"<h1 id=\"firstDiv\">Hello</h1>");  // REPLACES $firstDiv with the specified HTML string.
$firstDiv.wrap(
"<div id=\"container\"></div>");    // Wraps $firstDiv INSIDE of the newly specified div HTML.
$("div").wrapAll("<div></div>");        // Wraps $firstDiv and $secondDiv INSIDE of the newly
//   specified div HTML.

$("div").wrapInner("<div></div>");      // Wraps the contents of EACH div with the newly
//   specified div HTML.
});

Best-practice: use the most appropriate jQuery method to accomplish what you need in your code. Use these shorter, faster methods rather than simply setting the .text() or .html() on an element.

Chaining:
In jQuery, it is sometimes common to chain several statements together:

var $myClass = $("#myClass");

// Not Chained:
$myClass.addClass("newclass");
$myClass.css("border: 1px solid pink");
$myClass.removeClass("oldclass");
$myClass.css("color: orange");

// Chained:
$myClass.addClass("newclass").css("border: 1px solid pink").removeClass("oldclass").css("color: orange");

Chaining can make it so you can do everything in one state, but the downside is that statement is more difficult to read.

Best-practice: use discretion and limit chaining. Instead, use discrete statements as a rule unless chaining does not interfere with readability; or perhaps the chained-steps go together and seem more natural to be chained.

Using .toggleClass() versus .addClass():
The jQuery .toggleClass() method handles the logic of figuring out if a CSS class is already assigned to an element, and will then “toggle” whether it’s been added or not. In cases where a class might be added or removed often, toggleClass() is often a better approach which also requires less code.

Best-practice: if you will regularly go between adding a CSS class and removing it, use .toggleClass() instead, because it is less code and it already handles the logic of “what if the class is already assigned?” and vice versa.

The .hover() method:
Similar to toggleClass, the .hover() method handles a mouse over, and mouse out event in a tidier way, and should be used instead of manually handling the mouse over and mouse out events.

The “this” keyword:
When you are within a jQuery block, the “this” keyword refers to the result of the immediate jQuery selector. So, if you are inside of a code block, there is no need to look up that object again, you can get to it with the this keyword. For example:

$().ready(function () {
$("#mainLink").click(function () {
alert(this.id + ' was clicked');
});
});

Best-practice: use the “this” keyword instead of using another jQuery selector to re-find an object.

Content vs. Manipulation:
Use jQuery to manipulate the DOM. Using jQuery to dynamically create HTML should be avoided. Similarly, jQuery should be used to add or remove existing CSS classes, specific CSS attributes should not be set directly – this is for maintainability.

Best-practice: use jQuery to manipulate the DOM, add CSS classes, or removing CSS classes. Avoid using jQuery to create dynamic content.

Numbering sets and using for..each vs. for..next:
When using a for..each statement, instead of using your own counter, use the built-in one that is passed to the anonymous function that gets used. For example:

$("div").each(function (index) {
$(this).html(index + " " + $(this).html());
});

Best-practice: use the .each() method instead of going a JavaScript for..next. This .each() method is less code, has everything you need, and is easier to implement and maintain.

Quotation Marks:
You can use either single quotes or double quotes in JavaScript (and consequently in jQuery), as well as HTML. The key is really to simply be consistent.

Best-practice: it is consider a de facto standard to always use double-quotes for HTML attributes (e.g. <a href=”test.html”>test</a>). For JavaScript/jQuery, use double-quotes as well.

Naming Standards:
Use full words, when possible. When using well-known acronyms, names longer than 2 characters should be mixed case. All variables and identifiers should be camelCase. Variables that represent the result of a jQuery selector (or JavaScript object) should be prefixed with a “$”, as a matter of convention. Some examples:

var firstName = "";
var dbName = "";
var sourceDBName = "";
var sourceRdbmsName = "";
var rdbmsName = "";
var $firstNameTextBox = $("#firstNameTextBox");

AJAX calls:
There are several ways to make AJAX requests from jQuery. First, here is a list of the common ways to do this:

  • .get() is for doing an HTTP GET from a web service or page.
  • .ajax() gives you the most control over the request/response of any AJAX call.
  • .load() is for getting chunks of HTML or XML and inserting the results into an element on the page.
  • .getJSON() is for getting and easily processing JSON-formatted data.
  • .getScript() is for getting and executing external JavaScripts.
  • .post() is for doing an HTTP POST of data to a web service or page.

Here is an example implementation of reading XML (an RSS) feed and outputting some of the data that was retrieved:

Using .get():

$().ready(function () {
// Turn off caching
$.ajaxSetup({ cache: false });
// Establish some sort of error handling...
$(document).ajaxError(function (e, jqxhr, settings, exception) {
$("#firstDiv").html("Error from AJAX call: " + jqxhr.statusText);
});

// Show a message or spinner image
$("#firstDiv").html("Loading...");
// Make AJAX call, and do something with the data when it's done.
$.get("http://blogs.msdn.com/b/mainfeed.aspx?Type=BlogsOnly",

function (response, status, xhr) {
var $title = $("rss>channel>title", response).text();
var $link = $("rss>channel>link", response).text();
var $titleTag = $("<h1></h1>").text = $title;
var $linkTag = $("<a href=\"" + $link + "\">" + $title + "</a>")
$("#firstDiv").html($linkTag);
}, "xml");
});

Using .ajax():

$().ready(function () {
// Turn off caching
$.ajaxSetup({ cache: false });
// Establish some sort of error handling...
$(document).ajaxError(function (e, jqxhr, settings, exception) {
$("#firstDiv").html("Error from AJAX call: " + jqxhr.statusText);
});

// Show a message or spinner image
$("#firstDiv").html("Loading...");
// Make AJAX call, and do something with the data when it's done.
$.ajax({
url: "http://blogs.msdn.com/b/mainfeed.aspx?Type=BlogsOnly",
type: "GET",
dataType: "xml",

success: function (response, status, xhr) {
var $title = $("rss>channel>title", response).text();
var $link = $("rss>channel>link", response).text();
var $titleTag = $("<h1></h1>").text = $title;
var $linkTag = $("<a href=\"" + $link + "\">" + $title + "</a>")
$("#firstDiv").html($linkTag);
}
});
});

Using .load():

$().ready(function () {
// Turn off caching
$.ajaxSetup({ cache: false });
// Establish some sort of error handling...
$(document).ajaxError(function (e, jqxhr, settings, exception) {
$("#firstDiv").html("Error from AJAX call: " + jqxhr.statusText);
});

// Show a message or spinner image
$("#firstDiv").html("Loading...");

// Make AJAX call, and do something with the data when it's done.
$('#firstDiv').load("test.html", function () {
alert('Load was performed.');
});
});

Using .getJSON():

$().ready(function () {
// Turn off caching
$.ajaxSetup({ cache: false });
var $firstDiv = $("#firstDiv");
// Establish some sort of error handling...
$(document).ajaxError(function (e, jqxhr, settings, exception) {
$firstDiv.html("Error from AJAX call: " + jqxhr.statusText);
});

// Show a message or spinner image
$firstDiv.html("Loading...");

// Make AJAX call, and do something with the data when it's done.
$.getJSON("ExampleData.json", function (data) {

// Create an array to hold the list items
var items = [];

// For each element found, add a new <li> element.
$.each(data, function (key, val) {
items.push('<li id="' + key + '">' + val + '</li>');
});

// Clear out the firstDiv <div/> tag
$firstDiv.empty();
// Create a new, empty <ul/> to hold the elements
// then append it to the firstDiv <div/>
$('<ul/>', {
'class': 'my-new-list',
html: items.join('')
}).appendTo($firstDiv);
});
});

Using .getScript():

$().ready(function () {
$.getScript("myCustomScript.js", function () {
alert("Done loading.");
});
});

Using .post():

$.post("test.aspx",
{ name: "John", time: "2pm" },
function (data) {
alert("Post success: " + data);
});

Best-practice: Use getJSON() when getting JSON data, otherwise use the most specialized method that fits your need. When writing AJAX services, return JSON instead of XML, jQuery already natively understands how to work with it.

If you enjoyed this post, please consider leaving a comment or subscribing to the RSS feed to have future articles delivered to your feed reader.