jQuery debugging tips

I’ve been using jQuery a lot lately and occasionally ended up with strange errors — particularly given the tendency in JavaScript to use custom events, closures and callbacks.

Below are some gotchas to avoid.

$. versus $

If you use the dollar sign syntax for methods such as $.each(), it’s easy to make a mistake like the following:

$.('#container').append('foo'); // dodgy!

This leads to really puzzling error messages such as ‘Uncaught SyntaxError: Unexpected token (‘ (in Chrome) or ‘XML filter is applied to non-XML value (function (a, b) {return new (c.fn.init)(a, b);})’ (in Firefox).

Maybe this is another reason to use jQuery.each() not $.each();

ID selectors

This is so obvious, but it’s bitten me more than once.

When selecting an element by ID — especially if you’re used to using getElementById() — it’s easy to forget to add the hash character.

Make sure to use $(“#elementId”) not $(“elementId”).

Properties and attributes

Make sure whether you should be using .css, .attr or a (DOM) object property. For example: background-image is a CSS property, not an attribute.

DOM element or jQuery object?

It’s easy to miss the obvious…

For example, all a method on a video element like this:

    $(“#myVideo”)[0].play();

This, of course, will not work:

    $(“#myVideo”).play();

Synchronous and asynchronous

Be careful when mixing synchronous and asynchronous code.

This is not particularly a jQuery problem — here’s an example from Google Chrome Extensions (which make extensive use of callbacks):

function foo() {
var selectedTabId;
chrome.tabs.getSelected(null, function(tab) {
selectedTabId = tab.id;
});
// selectedTabId is still null
}

Don’t forget the “px”!

var  jGrabImg = $(““).attr(“src”, grabImgUrl).css({“right”: (videoRight – 10) + “px”, “top”: (videoTop + 10) + “px”});

ready() and setTimeout()

Again, this is not specifically a jQuery problem, but be aware of scope in $(document).ready(function() {…}); 

For example, variables declared inside the ready function are not visible to setTimeout code called via a string argument, which is evaluated in the context of Window:

$(document).ready(function() {
var foo = “blah”;
setTimeout(“alert(foo)”, 1000); // foo is undefined when alert is called
});

You can use a function argument like this, because :

$(document).ready(function() {
var foo = “blah”;
setTimeout(function(){alert(foo)}, 1000); // foo is defined
});

In Firefox and Chrome (at least) you can give the setTimeout method one or more arguments, like this:

$(document).ready(function() {
function f(arg) {
alert(arg);
}
var v= “blah”;
setTimeout(f, 100, v);
});

Alternatively you can use closures:

$(document).ready(function() {
(function () {
var arg = “blah”;
setTimeout(function(){alert(arg);}, 100);
})();
});

Callbacks and scope

Also watch out for scope in jQuery callbacks. For example:

MyClass.prototype = {
doSomething: function() {
$.getJSON(myUrl, function(data) {
// this.handleData(data) won’t work!
});
},
handleData: function(data) {
// do something with data
}
}

You’ll need to make ‘this’ available in the callback or, for static methods at least, name the function MyClass.handleData.

The same applies for each():

myJQueryObj.each(function(){ …})

Objects and arrays and trigger()

If you use an array as the argument to the jQuery trigger method, any associated bind callback will be called with multiple arguments, one for each item in the array. This can be confusing when triggering an event from a $.getJSON callback. If the JSON data object returned is an array and you use this object as an argument to a trigger call, it looks as if you are ‘sending’ a single object (an array), whereas on the receiving end, via bind, this is seen as multiple parameters.

About these ads

About Sam Dutton

I am a Developer Advocate for Google Chrome. I grew up in rural South Australia, went to university in Sydney, and have lived since 1986 in London, England. Twitter: @SW12
This entry was posted in Uncategorized and tagged , , . Bookmark the permalink.

2 Responses to jQuery debugging tips

  1. Vince Wooll says:

    Thanks Sam, I was puzzling over that stray $. myself.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s