Improve your jQuery - 25 excellent tips

http://www.tvidesign.co.uk/blog/improve-your-jque

Introduction

jQuery is awesome. I've been using it for about a year now and although I was impressed to begin with I'm liking it more and more the longer I use it and the more I find out about it's inner workings.

I'm no jQuery expert. I don't claim to be, so if there are mistakes in this article then feel free to correct me or make suggestions for improvements.

I'd call myself an "intermediate" jQuery user and I thought some others out there could benefit from all the little tips, tricks and techniques I've learned over the past year. The article also ended up being a lot longer than I thought it was going to be so I'll start with a table of contents so you can skip to the bits you're interested in.

Table of Contents

1. Load the framework from Google Code

Google have been hosting several JavaScript libraries for a while now on Google Code and there are several advantages to loading it from them instead of from your server. It saves on bandwidth, it'll load very quickly from Google's CDN and most importantly it'll already be cached if the user has visited a site which delivers it from Google Code.

This makes a lot of sense. How many sites out there are serving up identical copies of jQuery that aren't getting cached? It's easy to do too...

view plaincopy to clipboardprint?

  1. <script src="http://www.google.com/jsapi"></script>
  2. <script type="text/javascript">
  3. // Load jQuery
  4. google.load("jquery", "1.2.6");
  5. google.setOnLoadCallback(function() {
  6. // Your code goes here.
  7. });
  8. </script>
<script src="http://www.google.com/jsapi"></script>
<script type="text/javascript">

    // Load jQuery
    google.load("jquery", "1.2.6");

    google.setOnLoadCallback(function() {
        // Your code goes here.
    });
       
</script>
</pre>
<br />Or, you can just include a direct reference like this...<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-xml" start="1"><li class="alt"><span><span class="tag"><</span><span class="tag-name">script</span><span> </span><span class="attribute">src</span><span>=</span><span class="attribute-value">"http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"</span><span> </span><span class="attribute">type</span><span>=</span><span class="attribute-value">"text/javascript"</span><span class="tag">></span><span class="tag"></</span><span class="tag-name">script</span><span class="tag">></span><span>  </span></span></li></ol></div><pre  title="code" class="xml"><script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js" type="text/javascript"></script>
</pre>
<br /><a href="http://code.google.com/apis/ajaxlibs/documentation/index.html">Full instructions here</a>
<br /><br /><br /><a name="tip2"></a>
<h3>2. Use a cheat sheet</h3><br />
<br />Not just a jQuery tip, there are some great cheat sheets out there
for most languages. It's handy having every function on a printable A4
sheet for reference and luckily these guys have produced a couple of
nice ones..<br /><br /><a href="http://www.gscottolson.com/weblog/2008/01/11/jquery-cheat-sheet/">http://www.gscottolson.com/weblog/2008/01/11/jquery-cheat-sheet/</a>
<br /><a href="http://colorcharge.com/jquery/">http://colorcharge.com/jquery/</a>
 <br /><br /><br /><a name="tip3"></a>
<h3>3. Combine all your scripts and minify them</h3><br />
<br />OK, a general JavaScript tip here. But any big project that uses
lots of jQuery probably uses lots of plugins (this site uses easing,
localScroll, lightbox and preload) so it's usually applicable.<br /><br />Browsers
can't load scripts concurrently (well, most can't, yet), which means
that if you've got several scripts downloading one at a time then
you're really slowing down the loading of your page. So, assuming the
scrips are being loaded on every page then you should consider
combining them into one long script before deploying.<br /><br />Some of
the plugins will already be minified, but you should consider packing
your scripts and any that aren't already. It only takes a few seconds.
I'm personally a fan of <a href="http://dean.edwards.name/packer/">Packer by Dean Edwards</a>
<br /><br /><br /><a name="tip4"></a>
<h3>4. Use Firebug's excellent console logging facilities</h3><br />
<br />If you haven't already installed Firebug then you really should.
Aside from many other useful features such as allowing you to inspect
http traffic and find problems with your CSS it has excellent logging
commands that allow you to easily debug your scripts.<br /><br /><a href="http://getfirebug.com/console.html">Here's a full explanation of all of it's features</a><br />
<br />My favourite features are "console.info", which you can use to just
dump messages and variables to the screen without having to use alert
boxes and "console.time" which allows you to easily set up a timer to
wrap a bunch of code and see how long it takes. They're all really easy
to use too...<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span>console.time(</span><span class="string">'create list'</span><span>);  </span></span></li><li class=""><span>  </span></li><li class="alt"><span><span class="keyword">for</span><span> (i = 0; i < 1000; i++) {  </span></span></li><li class=""><span>    <span class="keyword">var</span><span> myList = $(</span><span class="string">'.myList'</span><span>);  </span></span></li><li class="alt"><span>    myList.append(<span class="string">'This is list item '</span><span> + i);  </span></span></li><li class=""><span>}  </span></li><li class="alt"><span>  </span></li><li class=""><span>console.timeEnd(<span class="string">'create list'</span><span>);  </span></span></li></ol></div><pre  title="code" class="Jscript">console.time('create list');

for (i = 0; i < 1000; i++) {
    var myList = $('.myList');
    myList.append('This is list item ' + i);
}

console.timeEnd('create list');
</pre>
<br />In this instance I've deliberately written some very inefficient
code! In the next few tips I'll show you how we can use the timer to
show some improvements which can be made.<br /><br /><br /><br /><a name="tip5"></a>
<h3>5. Keep selection operations  to a minimum by caching</h3><br />
<br />jQuery selectors are awesome. They make selecting any element on
the page incredibly simple, but internally they have to do a fair
amount of work and if you go mad with them you might find things
starting to get pretty slow.<br /><br />If you're selecting the same
element time and time again (in a loop for example) then you can just
select it once and keep it in memory while you manipulate it to your
heart's content. Take the following example where we add items to an
unordered list using a loop.<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span class="keyword">for</span><span> (i = 0; i < 1000; i++) {  </span></span></li><li class=""><span>    <span class="keyword">var</span><span> myList = $(</span><span class="string">'.myList'</span><span>);  </span></span></li><li class="alt"><span>    myList.append(<span class="string">'This is list item '</span><span> + i);  </span></span></li><li class=""><span>}  </span></li></ol></div><pre  title="code" class="Jscript">for (i = 0; i < 1000; i++) {
    var myList = $('.myList');
    myList.append('This is list item ' + i);
}
</pre>
<br />That takes 1066 milliseconds on my PC in Firefox 3 (imagine how
long it would IE6!), which is pretty slow in JavaScript terms. Now take
a look at the following code where we use the selector just once.<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span class="keyword">var</span><span> myList = $(</span><span class="string">'.myList'</span><span>);  </span></span></li><li class=""><span>  </span></li><li class="alt"><span><span class="keyword">for</span><span> (i = 0; i < 1000; i++) {  </span></span></li><li class=""><span>    myList.append(<span class="string">'This is list item '</span><span> + i);  </span></span></li><li class="alt"><span>}  </span></li></ol></div><pre  title="code" class="Jscript">var myList = $('.myList');

for (i = 0; i < 1000; i++) {
    myList.append('This is list item ' + i);
}
</pre>
<br />That only takes 224 milliseconds, more than 4x faster, just by moving one line of code.<br /><br /><br /><br /><a name="tip6"></a>
<h3>6. Keep DOM manipulation to a minimum</h3><br />
<br />We can make the code from the previous tip even faster by cutting
down on the number of times we insert into the DOM. DOM insertion
operations like .append() .prepend() .after() and .wrap() are
relatively costly and performing lots of them can really slow things
down.<br /><br />All we need to do is use string concatenation to build the
list and then use a single function to add them to your unordered list
like .html() is much quicker. Take the following example...<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span class="keyword">var</span><span> myList = $(</span><span class="string">'#myList'</span><span>);  </span></span></li><li class=""><span>  </span></li><li class="alt"><span><span class="keyword">for</span><span> (i=0; i<1000; i++){  </span></span></li><li class=""><span>    myList.append(<span class="string">'This is list item '</span><span> + i);  </span></span></li><li class="alt"><span>}  </span></li></ol></div><pre  title="code" class="Jscript">var myList = $('#myList');

for (i=0; i<1000; i++){
    myList.append('This is list item ' + i);
}
</pre>
<br />On my PC that takes 216 milliseconds , just over a 1/5th of a
second, but if we build the list items as a string first and use the
HTML method to do the insert, like this....<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span class="keyword">var</span><span> myList = $(</span><span class="string">'.myList'</span><span>);  </span></span></li><li class=""><span><span class="keyword">var</span><span> myListItems = </span><span class="string">''</span><span>;  </span></span></li><li class="alt"><span>  </span></li><li class=""><span><span class="keyword">for</span><span> (i = 0; i < 1000; i++) {  </span></span></li><li class="alt"><span>    myListItems += <span class="string">'<li>This is list item '</span><span> + i + </span><span class="string">'</li>'</span><span>;  </span></span></li><li class=""><span>}  </span></li><li class="alt"><span>  </span></li><li class=""><span>myList.html(myListItems);  </span></li></ol></div><pre  title="code" class="Jscript">var myList = $('.myList');
var myListItems = '';

for (i = 0; i < 1000; i++) {
    myListItems += '<li>This is list item ' + i + '</li>';
}

myList.html(myListItems);
</pre>
<br />That takes 185 milliseconds, not much quicker but that's another 31 milliseconds off the time.<br /><br /><br /><br /><a name="tip7"></a>
<h3>7. Wrap everything in a single element when doing any kind of DOM insertion</h3><br />
<br />OK, don't ask me why this one works (I'm sure a more experienced coder will explain).<br /><br />In
our last example we inserted 1000 list items into an unordered list
using the .html() method. If we had have wrapped them in the UL tag
before doing the insert and inserted the completed UL into another tag
(a DIV) then we're effectively only inserting 1 tag, not 1000, which
seems to be much quicker. Like this...<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span class="keyword">var</span><span> myList = $(</span><span class="string">'.myList'</span><span>);  </span></span></li><li class=""><span><span class="keyword">var</span><span> myListItems = </span><span class="string">'<ul>'</span><span>;  </span></span></li><li class="alt"><span>  </span></li><li class=""><span><span class="keyword">for</span><span> (i = 0; i < 1000; i++) {  </span></span></li><li class="alt"><span>    myListItems += <span class="string">'<li>This is list item '</span><span> + i + </span><span class="string">'</li>'</span><span>;  </span></span></li><li class=""><span>}  </span></li><li class="alt"><span>  </span></li><li class=""><span>myListItems += <span class="string">'</ul>'</span><span>;  </span></span></li><li class="alt"><span>myList.html(myListItems);  </span></li></ol></div><pre  title="code" class="Jscript">var myList = $('.myList');
var myListItems = '<ul>';

for (i = 0; i < 1000; i++) {
    myListItems += '<li>This is list item ' + i + '</li>';
}

myListItems += '</ul>';
myList.html(myListItems);
</pre>
<br />The time is now only 19 milliseconds, a massive improvement, 50x faster than our first example.<br /><br /><br /><br /><a name="tip8"></a>
<h3>8. Use IDs instead of classes wherever possible</h3><br />
<br />jQuery makes selecting DOM elements using classes as easy as
selecting elements by ID used to be, so it's tempting to use classes
much more liberally than before. It's still much better to select by ID
though because jQuery uses the browser's native method (getElementByID)
to do this and doesn't have to do any of it's own DOM traversal, which
is much faster. How much faster? Let's find out.<br /><br />I'll use the
previous example and adapt it so each LI we create has a unique class
added to it. Then I'll loop through and select each one once.<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span class="comment">// Create our list</span><span>  </span></span></li><li class=""><span><span class="keyword">var</span><span> myList = $(</span><span class="string">'.myList'</span><span>);  </span></span></li><li class="alt"><span><span class="keyword">var</span><span> myListItems = </span><span class="string">'<ul>'</span><span>;  </span></span></li><li class=""><span>  </span></li><li class="alt"><span><span class="keyword">for</span><span> (i = 0; i < 1000; i++) {  </span></span></li><li class=""><span>    myListItems += <span class="string">'<li class="listItem'</span><span> + i + </span><span class="string">'">This is a list item</li>'</span><span>;  </span></span></li><li class="alt"><span>}  </span></li><li class=""><span>  </span></li><li class="alt"><span>myListItems += <span class="string">'</ul>'</span><span>;  </span></span></li><li class=""><span>myList.html(myListItems);  </span></li><li class="alt"><span>  </span></li><li class=""><span><span class="comment">// Select each item once</span><span>  </span></span></li><li class="alt"><span><span class="keyword">for</span><span> (i = 0; i < 1000; i++) {  </span></span></li><li class=""><span>    <span class="keyword">var</span><span> selectedItem = $(</span><span class="string">'.listItem'</span><span> + i);  </span></span></li><li class="alt"><span>}  </span></li></ol></div><pre  title="code" class="Jscript">// Create our list
var myList = $('.myList');
var myListItems = '<ul>';

for (i = 0; i < 1000; i++) {
    myListItems += '<li class="listItem' + i + '">This is a list item</li>';
}

myListItems += '</ul>';
myList.html(myListItems);

// Select each item once
for (i = 0; i < 1000; i++) {
    var selectedItem = $('.listItem' + i);
}
</pre>
<br />Just as I thought my browser had hung, it finished, in 5066
milliseconds (over 5 seconds). So i modified the code to give each item
an ID instead of a class and then selected them using the ID.<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span class="comment">// Create our list</span><span>  </span></span></li><li class=""><span><span class="keyword">var</span><span> myList = $(</span><span class="string">'.myList'</span><span>);  </span></span></li><li class="alt"><span><span class="keyword">var</span><span> myListItems = </span><span class="string">'<ul>'</span><span>;  </span></span></li><li class=""><span>  </span></li><li class="alt"><span><span class="keyword">for</span><span> (i = 0; i < 1000; i++) {  </span></span></li><li class=""><span>    myListItems += <span class="string">'<li >// Create our list
var myList = $('.myList');
var myListItems = '<ul>';

for (i = 0; i < 1000; i++) {
    myListItems += '<li >This is a list item</li>';
}

myListItems += '</ul>';
myList.html(myListItems);

// Select each item once
for (i = 0; i < 1000; i++) {
    var selectedItem = $('#listItem' + i);
}
</pre>
<br />This time it only took 61 milliseconds. Nearly 100x faster.<br /><br /><br /><br /><a name="tip9"></a>
<h3>9. Give your selectors a context</h3><br />
<br />By default, when you use a selector such as $('.myDiv') the whole
of the DOM will be traversed, which depending on the page could be
expensive.<br /><br />The jQuery function takes a second parameter when performing a selection.<br /><br /><strong>jQuery( expression, context )</strong><br />
<br />By providing a context to the selector, you give it an element to
start searching within so that it doesn't have to traverse the whole of
the DOM.<br /><br />To demonstrate this, let's take the first block of code
from the tip above. It creates an unordered list with 1000 items, each
with an individual class. It then loops through and selects each item
once. You'll remember that when selecting by class it took just over 5
seconds to select all 1000 of them using this selector.<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span class="keyword">var</span><span> selectedItem = $(</span><span class="string">'#listItem'</span><span> + i);  </span></span></li></ol></div><pre  title="code" class="Jscript">var selectedItem = $('#listItem' + i);
</pre>
<br />I then added a context so that it was only running the selector inside the unordered list, like this...<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span class="keyword">var</span><span> selectedItem = $(</span><span class="string">'#listItem'</span><span> + i, $(</span><span class="string">'.myList'</span><span>));  </span></span></li></ol></div><pre  title="code" class="Jscript">var selectedItem = $('#listItem' + i, $('.myList'));
</pre>
<br />It still took 3818 milliseconds because it's still horribly
inefficient, but that's more than a 25% speed increase by making a
small modification to a selector.<br /><br /><br /><br /><a name="tip10"></a>
<h3>10. Use chaining properly</h3><br />
<br />One of the coolest things about jQuery is it's ability to chain
method calls together. So, for example, if you want to switch the class
on an element.<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span>$(</span><span class="string">'myDiv'</span><span>).removeClass(</span><span class="string">'off'</span><span>).addClass(</span><span class="string">'on'</span><span>);  </span></span></li></ol></div><pre  title="code" class="Jscript">$('myDiv').removeClass('off').addClass('on');
</pre>
<br />If you're anything like me then you probably learned that in your
first 5 minutes of reading about jQuery but it goes further than that.
Firstly, it still works across line breaks (because jQuery =
JavaScript), which means you can write neat code like this...<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span>$(</span><span class="string">'#mypanel'</span><span>)  </span></span></li><li class=""><span>    .find(<span class="string">'TABLE .firstCol'</span><span>)  </span></span></li><li class="alt"><span>    .removeClass(<span class="string">'.firstCol'</span><span>)  </span></span></li><li class=""><span>    .css(<span class="string">'background'</span><span> : </span><span class="string">'red'</span><span>)  </span></span></li><li class="alt"><span>    .append(<span class="string">'<span>This cell is now red</span>'</span><span>);  </span></span></li></ol></div><pre  title="code" class="Jscript">$('#mypanel')
    .find('TABLE .firstCol')
    .removeClass('.firstCol')
    .css('background' : 'red')
    .append('<span>This cell is now red</span>');
</pre>
<br />Making a habit of using chaining automatically helps you to cut down on your selector use too.<br /><br />But
it goes further than that. Let's say that you want to perform several
functions on an element but one of the first functions changes the
element in some way, like this...<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span>$(</span><span class="string">'#myTable'</span><span>).find(</span><span class="string">'.firstColumn'</span><span>).css(</span><span class="string">'background'</span><span>,</span><span class="string">'red'</span><span>);  </span></span></li></ol></div><pre  title="code" class="Jscript">$('#myTable').find('.firstColumn').css('background','red');
</pre>
<br />We've selected a table, drilled down to find cells with a class of "firstColumn" and coloured them in red.<br /><br />Let's
say we now want to colour all the cells with a class of "lastColumn"
blue. Because we've used the find() funciton we've filtered out all the
cells that don't have a class of "firstColumn" so we need to use the
selector again to get the table element and we can't continue chaining,
right? Luckily jQuery has an end() function which actually reverts back
to the previous unaltered selection so you can carry on chaining, like
this...<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span>$(</span><span class="string">'#myTable'</span><span>)  </span></span></li><li class=""><span>    .find(<span class="string">'.firstColumn'</span><span>)  </span></span></li><li class="alt"><span>        .css(<span class="string">'background'</span><span>,</span><span class="string">'red'</span><span>)  </span></span></li><li class=""><span>    .end()  </span></li><li class="alt"><span>    .find(<span class="string">'.lastColumn'</span><span>)  </span></span></li><li class=""><span>        .css(<span class="string">'background'</span><span>,</span><span class="string">'blue'</span><span>);  </span></span></li></ol></div><pre  title="code" class="Jscript">$('#myTable')
    .find('.firstColumn')
        .css('background','red')
    .end()
    .find('.lastColumn')
        .css('background','blue');
</pre>
<br />It's also easier than you might think to write your own jQuery
function which can chain. All you have to do is write a function which
modifies an element and returns it.<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span>$.fn.makeRed = </span><span class="keyword">function</span><span>() {  </span></span></li><li class=""><span>    <span class="keyword">return</span><span> $(</span><span class="keyword">this</span><span>).css(</span><span class="string">'background'</span><span>, </span><span class="string">'red'</span><span>);  </span></span></li><li class="alt"><span>}  </span></li><li class=""><span>  </span></li><li class="alt"><span>$(<span class="string">'#myTable'</span><span>).find(</span><span class="string">'.firstColumn'</span><span>).makeRed().append(</span><span class="string">'hello'</span><span>);  </span></span></li></ol></div><pre  title="code" class="Jscript">$.fn.makeRed = function() {
    return $(this).css('background', 'red');
}

$('#myTable').find('.firstColumn').makeRed().append('hello');
</pre>
<br />How easy was that?<br /><br /><br /><br /><a name="tip11"></a>
<h3>11. Learn to use animate properly</h3><br />
<br />When I first started using jQuery I loved the fact that it was easy
to use the pre-defined animations like slideDown() and fadeIn() to get
some really cool effects incredibly easy. It's easy to take things
further though because jQuery's animate() method is very easy to use
and very powerful. In fact, is you look at the jQuery source code
you'll see that internally those methods are just shortcuts which use
the animate() function.<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span>slideDown: </span><span class="keyword">function</span><span>(speed,callback){  </span></span></li><li class=""><span>    <span class="keyword">return</span><span> </span><span class="keyword">this</span><span>.animate({height: </span><span class="string">"show"</span><span>}, speed, callback);  </span></span></li><li class="alt"><span>},  </span></li><li class=""><span>  </span></li><li class="alt"><span>fadeIn: <span class="keyword">function</span><span>(speed, callback){  </span></span></li><li class=""><span>    <span class="keyword">return</span><span> </span><span class="keyword">this</span><span>.animate({opacity: </span><span class="string">"show"</span><span>}, speed, callback);  </span></span></li><li class="alt"><span>}  </span></li></ol></div><pre  title="code" class="Jscript">slideDown: function(speed,callback){
    return this.animate({height: "show"}, speed, callback);
},

fadeIn: function(speed, callback){
    return this.animate({opacity: "show"}, speed, callback);
}
</pre>
<br />The animate() method simply takes any CSS style and smoothly
transitions it from one value to another. So, you can change the width,
height, opacity, background-color, top, left, margin, color, font-size,
anything you want.<br /><br />This is how easy it is to animate all your menu items grow to 100 pixels high when you roll over them.<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span>$(</span><span class="string">'#myList li'</span><span>).mouseover(</span><span class="keyword">function</span><span>() {  </span></span></li><li class=""><span>    $(<span class="keyword">this</span><span>).animate({</span><span class="string">"height"</span><span>: 100}, </span><span class="string">"slow"</span><span>);  </span></span></li><li class="alt"><span>});  </span></li></ol></div><pre  title="code" class="Jscript">$('#myList li').mouseover(function() {
    $(this).animate({"height": 100}, "slow");
});
</pre>
<br />Unlike other jQuery functions, animations are automatically queued,
so if you want to run a second animation once the first is finished
then just call the animate method twice, no callback necessary.<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span>$(</span><span class="string">'#myBox'</span><span>).mouseover(</span><span class="keyword">function</span><span>() {  </span></span></li><li class=""><span>    $(<span class="keyword">this</span><span>).animate({ </span><span class="string">"width"</span><span>: 200 }, </span><span class="string">"slow"</span><span>);  </span></span></li><li class="alt"><span>    $(<span class="keyword">this</span><span>).animate({</span><span class="string">"height"</span><span>: 200}, </span><span class="string">"slow"</span><span>);  </span></span></li><li class=""><span>});  </span></li></ol></div><pre  title="code" class="Jscript">$('#myBox').mouseover(function() {
    $(this).animate({ "width": 200 }, "slow");
    $(this).animate({"height": 200}, "slow");
});
</pre>
<br />If you want the animations to happen concurrently then just put both styles in the params object of a single call, like this...<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span>$(</span><span class="string">'#myBox'</span><span>).mouseover(</span><span class="keyword">function</span><span>() {  </span></span></li><li class=""><span>    $(<span class="keyword">this</span><span>).animate({ </span><span class="string">"width"</span><span>: 200, </span><span class="string">"height"</span><span>: 200 }, </span><span class="string">"slow"</span><span>);  </span></span></li><li class="alt"><span>});  </span></li></ol></div><pre  title="code" class="Jscript">$('#myBox').mouseover(function() {
    $(this).animate({ "width": 200, "height": 200 }, "slow");
});
</pre>
<br />You can animate any property that's numeric. You can also download plugins to help you animate properties that aren't, like <a href="http://plugins.jquery.com/project/color">colors and background colors</a>
<br /><br /><br /><a name="tip12"></a>
<h3>12. Learn about event delegation</h3><br />
<br />jQuery makes it easier than ever to attach events to elements in
the DOM unobtrusively, which is great, but adding too many events is
inefficient. Event delegation allows you to add less events to achieve
the same result in many situations. The best way to illustrate this is
with an example...<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span>$(</span><span class="string">'#myTable TD'</span><span>).click(</span><span class="keyword">function</span><span>(){  </span></span></li><li class=""><span>    $(<span class="keyword">this</span><span>).css(</span><span class="string">'background'</span><span>, </span><span class="string">'red'</span><span>);  </span></span></li><li class="alt"><span>});  </span></li></ol></div><pre  title="code" class="Jscript">$('#myTable TD').click(function(){
    $(this).css('background', 'red');
});
</pre>
<br />A simple function which turns cells in a table red when you click
on them. Let's say that you've got a grid with 10 columns and 50 rows
though, that's 500 events bound. Wouldn't it be neater if we could just
attach a single event to the table and when the table is clicked have
the event handler work out which cell was clicked before turning it red?<br /><br />Well that's exactly what event delegation is and it's easy to implement...<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span>$(</span><span class="string">'#myTable'</span><span>).click(</span><span class="keyword">function</span><span>(e) {  </span></span></li><li class=""><span>    <span class="keyword">var</span><span> clicked = $(e.target);  </span></span></li><li class="alt"><span>    clicked.css(<span class="string">'background'</span><span>, </span><span class="string">'red'</span><span>);  </span></span></li><li class=""><span>});  </span></li></ol></div><pre  title="code" class="Jscript">$('#myTable').click(function(e) {
    var clicked = $(e.target);
    clicked.css('background', 'red');
});
</pre>
<br />'e' contains information about the event, including the target
element that actually received the click. All we have to do is inspect
it to see which cell was actually clicked. Much neater.<br /><br />Event
delegation has another benefit. Normally, When you bind a handler to a
collection of elements it gets attached to those elements and those
elements only. If you add new elements to the DOM which would have been
matched by the selector then they don't have the event handler bound to
them (are you following me?) then nothing will happen.<br /><br />When
using event delegation you can add as many matching elements to the DOM
as you like after the event is bound and they work too.<br /><br /><br /><br /><a name="tip13"></a>
<h3>13. Use classes to store state</h3><br />
<br />This is the most basic way of storing information about a block of
html. jQuery is great at manipulating elements based upon their
classes, so if you need to store information about the state of an
element then why not add an extra class to store it?<br /><br />Here's an
example. We want to create an expanding menu. When you click the button
we want the panel to slideDown() if it's currently closed, or slideUp()
if it's currently open. We'll start with the HTML<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-xml" start="1"><li class="alt"><span><span class="tag"><</span><span class="tag-name">div</span><span> </span><span class="attribute">class</span><span>=</span><span class="attribute-value">"menuItem expanded"</span><span class="tag">></span><span>  </span></span></li><li class=""><span>    <span class="tag"><</span><span class="tag-name">div</span><span> </span><span class="attribute">class</span><span>=</span><span class="attribute-value">"button"</span><span class="tag">></span><span>  </span></span></li><li class="alt"><span>        click me  </span></li><li class=""><span>    <span class="tag"></</span><span class="tag-name">div</span><span class="tag">></span><span>  </span></span></li><li class="alt"><span>    <span class="tag"><</span><span class="tag-name">div</span><span> </span><span class="attribute">class</span><span>=</span><span class="attribute-value">"panel"</span><span class="tag">></span><span>  </span></span></li><li class=""><span>        <span class="tag"><</span><span class="tag-name">ul</span><span class="tag">></span><span>  </span></span></li><li class="alt"><span>            <span class="tag"><</span><span class="tag-name">li</span><span class="tag">></span><span>Menu item 1</span><span class="tag"></</span><span class="tag-name">li</span><span class="tag">></span><span>  </span></span></li><li class=""><span>            <span class="tag"><</span><span class="tag-name">li</span><span class="tag">></span><span>Menu item 2</span><span class="tag"></</span><span class="tag-name">li</span><span class="tag">></span><span>  </span></span></li><li class="alt"><span>            <span class="tag"><</span><span class="tag-name">li</span><span class="tag">></span><span>Menu item 3</span><span class="tag"></</span><span class="tag-name">li</span><span class="tag">></span><span>  </span></span></li><li class=""><span>        <span class="tag"></</span><span class="tag-name">ul</span><span class="tag">></span><span>  </span></span></li><li class="alt"><span>    <span class="tag"></</span><span class="tag-name">div</span><span class="tag">></span><span>  </span></span></li><li class=""><span><span class="tag"></</span><span class="tag-name">div</span><span class="tag">></span><span>  </span></span></li></ol></div><pre  title="code" class="xml"><div class="menuItem expanded">
    <div class="button">
        click me
    </div>
    <div class="panel">
        <ul>
            <li>Menu item 1</li>
            <li>Menu item 2</li>
            <li>Menu item 3</li>
        </ul>
    </div>
</div>
</pre>
<br />Very simple! We've just added an extra class to the wrapper div
which serves no other purpose other than to tell us the state of the
item. So all we need is a click event handler which performs slideUp()
or slideDown() on the corresponding panel when the button is clicked.<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span>$(</span><span class="string">'.button'</span><span>).click(</span><span class="keyword">function</span><span>() {  </span></span></li><li class=""><span>  </span></li><li class="alt"><span>    <span class="keyword">var</span><span> menuItem = $(</span><span class="keyword">this</span><span>).parent();  </span></span></li><li class=""><span>    <span class="keyword">var</span><span> panel = menuItem.find(</span><span class="string">'.panel'</span><span>);  </span></span></li><li class="alt"><span>  </span></li><li class=""><span>    <span class="keyword">if</span><span> (menuItem.hasClass(</span><span class="string">"expanded"</span><span>)) {  </span></span></li><li class="alt"><span>        menuItem.removeClass(<span class="string">'expanded'</span><span>).addClass(</span><span class="string">'collapsed'</span><span>);  </span></span></li><li class=""><span>        panel.slideUp();  </span></li><li class="alt"><span>    }  </span></li><li class=""><span>    <span class="keyword">else</span><span> </span><span class="keyword">if</span><span> (menuItem.hasClass(</span><span class="string">"collapsed"</span><span>)) {  </span></span></li><li class="alt"><span>        menuItem.removeClass(<span class="string">'collapsed'</span><span>).addClass(</span><span class="string">'expanded'</span><span>);  </span></span></li><li class=""><span>        panel.slideDown();  </span></li><li class="alt"><span>    }  </span></li><li class=""><span>});  </span></li></ol></div><pre  title="code" class="Jscript">$('.button').click(function() {

    var menuItem = $(this).parent();
    var panel = menuItem.find('.panel');

    if (menuItem.hasClass("expanded")) {
        menuItem.removeClass('expanded').addClass('collapsed');
        panel.slideUp();
    }
    else if (menuItem.hasClass("collapsed")) {
        menuItem.removeClass('collapsed').addClass('expanded');
        panel.slideDown();
    }
});
</pre>
<br />That's a very simple example, but you can add extra classes for
storing all sorts of information about an element or HTML fragment.<br /><br />However, in all but simple cases it's probably better to use the next tip.<br /><br /><br /><br /><a name="tip14"></a>
<h3>14. Even better, use jQuery's internal data() method to store state</h3><br />
<br />It's not very well documented for some reason but jQuery has an
internal data() method which can be used to store information in
key/value pairs against any DOM element. Storing a piece of data is as
simple as this...<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span>$(</span><span class="string">'#myDiv'</span><span>).data(</span><span class="string">'currentState'</span><span>, </span><span class="string">'off'</span><span>);  </span></span></li></ol></div><pre  title="code" class="Jscript">$('#myDiv').data('currentState', 'off');
</pre>
<br />We can amend the example from the previous tip. We'll use the same
HTML (with the "expanded" class removed) and use the data() function
instead.<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span>$(</span><span class="string">'.button'</span><span>).click(</span><span class="keyword">function</span><span>() {  </span></span></li><li class=""><span>  </span></li><li class="alt"><span>    <span class="keyword">var</span><span> menuItem = $(</span><span class="keyword">this</span><span>).parent();  </span></span></li><li class=""><span>    <span class="keyword">var</span><span> panel = menuItem.find(</span><span class="string">'.panel'</span><span>);  </span></span></li><li class="alt"><span>  </span></li><li class=""><span>    <span class="keyword">if</span><span> (menuItem.data(</span><span class="string">'collapsed'</span><span>)) {  </span></span></li><li class="alt"><span>        menuItem.data(<span class="string">'collapsed'</span><span>, </span><span class="keyword">false</span><span>);  </span></span></li><li class=""><span>        panel.slideDown();    </span></li><li class="alt"><span>    }  </span></li><li class=""><span>    <span class="keyword">else</span><span> {  </span></span></li><li class="alt"><span>        menuItem.data(<span class="string">'collapsed'</span><span>, </span><span class="keyword">true</span><span>);  </span></span></li><li class=""><span>        panel.slideUp();  </span></li><li class="alt"><span>    }  </span></li><li class=""><span>});  </span></li></ol></div><pre  title="code" class="Jscript">$('.button').click(function() {

    var menuItem = $(this).parent();
    var panel = menuItem.find('.panel');

    if (menuItem.data('collapsed')) {
        menuItem.data('collapsed', false);
        panel.slideDown();  
    }
    else {
        menuItem.data('collapsed', true);
        panel.slideUp();
    }
});
</pre>
<br />I'm sure you'll agree this is much neater. For more information about data() and removeData(), see this page...<br /><br /><a href="http://docs.jquery.com/Internals">jQuery internals</a>
<br /><br /><br /><a name="tip15"></a>
<h3>15. Write your own selectors</h3><br />
<br />jQuery has loads of built-in selectors for selecting elements by
ID, class, tag, attribute and many more. But what do you do when you
need to select elements based upon something else and jQuery doesn't
have a selector?<br /><br />Well, one answer would be to add classes to the
elements from the start and use those to select them, but it turns out
that it's not hard to extend jQuery to add new selectors.<br /><br />The best way to demonstrate is with an example.<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span>$.extend($.expr[</span><span class="string">':'</span><span>], {  </span></span></li><li class=""><span>    over100pixels: <span class="keyword">function</span><span>(a) {  </span></span></li><li class="alt"><span>        <span class="keyword">return</span><span> $(a).height() > 100;  </span></span></li><li class=""><span>    }  </span></li><li class="alt"><span>});  </span></li><li class=""><span>  </span></li><li class="alt"><span>$(<span class="string">'.box:over100pixels'</span><span>).click(</span><span class="keyword">function</span><span>() {  </span></span></li><li class=""><span>    alert(<span class="string">'The element you clicked is over 100 pixels high'</span><span>);  </span></span></li><li class="alt"><span>});  </span></li></ol></div><pre  title="code" class="Jscript">$.extend($.expr[':'], {
    over100pixels: function(a) {
        return $(a).height() > 100;
    }
});

$('.box:over100pixels').click(function() {
    alert('The element you clicked is over 100 pixels high');
});
</pre>
<br />The first block of code creates a custom selector which finds any
element that is more than 100 pixels tall. The second block just uses
it to add a click handler to all those elements.<br /><br />I won't go into
any more detail here but you can imagine how powerful this is and if
you search google for "custom jquery selector" you'll find loads of
great examples.<br /><br /><br /><br /><a name="tip16"></a>
<h3>16. Streamline your HTML and modify it once the page has loaded</h3><br />
<br />The title might not make a lot of sense but this tip can
potentially neaten up your code, reduce the weight and download time of
your page and help your SEO. Take the following HTML for example...<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span><div </span><span class="keyword">class</span><span>=</span><span class="string">"fieldOuter"</span><span>>  </span></span></li><li class=""><span>    <div <span class="keyword">class</span><span>=</span><span class="string">"inner"</span><span>>  </span></span></li><li class="alt"><span>        <div <span class="keyword">class</span><span>=</span><span class="string">"field"</span><span>>This is field number 1</div>  </span></span></li><li class=""><span>    </div>  </span></li><li class="alt"><span>    <div <span class="keyword">class</span><span>=</span><span class="string">"errorBar"</span><span>>  </span></span></li><li class=""><span>        <div <span class="keyword">class</span><span>=</span><span class="string">"icon"</span><span>><img src=</span /><span class="string">"icon.png"</span><span> alt=</span><span class="string">"icon"</span><span> /></div>  </span></span></li><li class="alt"><span>        <div <span class="keyword">class</span><span>=</span><span class="string">"message"</span><span>><span>This is an error message</span></div>  </span></span></li><li class=""><span>    </div>  </span></li><li class="alt"><span></div>  </span></li><li class=""><span><div <span class="keyword">class</span><span>=</span><span class="string">"fieldOuter"</span><span>>  </span></span></li><li class="alt"><span>    <div <span class="keyword">class</span><span>=</span><span class="string">"inner"</span><span>>  </span></span></li><li class=""><span>        <div <span class="keyword">class</span><span>=</span><span class="string">"field"</span><span>>This is field number 2</div>  </span></span></li><li class="alt"><span>    </div>  </span></li><li class=""><span>    <div <span class="keyword">class</span><span>=</span><span class="string">"errorBar"</span><span>>  </span></span></li><li class="alt"><span>        <div <span class="keyword">class</span><span>=</span><span class="string">"icon"</span><span>><img src=</span /><span class="string">"icon.png"</span><span> alt=</span><span class="string">"icon"</span><span> /></div>  </span></span></li><li class=""><span>        <div <span class="keyword">class</span><span>=</span><span class="string">"message"</span><span>><span>This is an error message</span></div>  </span></span></li><li class="alt"><span>    </div>  </span></li><li class=""><span></div>  </span></li></ol></div><pre  title="code" class="Jscript"><div class="fieldOuter">
    <div class="inner">
        <div class="field">This is field number 1</div>
    </div>
    <div class="errorBar">
        <div class="icon"><img src="icon.png" alt="icon" /></div>
        <div class="message"><span>This is an error message</span></div>
    </div>
</div>
<div class="fieldOuter">
    <div class="inner">
        <div class="field">This is field number 2</div>
    </div>
    <div class="errorBar">
        <div class="icon"><img src="icon.png" alt="icon" /></div>
        <div class="message"><span>This is an error message</span></div>
    </div>
</div>
</pre>
<br />That's an example of how a form might be marked up, modified
slightly for illustrative purposes. I'm sure you'll agree it's pretty
ugly and if you had a long form you'd end up with a fairly long ugly
page. It's be nicer if you could just put this in your HTML.<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-xml" start="1"><li class="alt"><span><span class="tag"><</span><span class="tag-name">div</span><span> </span><span class="attribute">class</span><span>=</span><span class="attribute-value">"field"</span><span class="tag">></span><span>This is field 1</span><span class="tag"></</span><span class="tag-name">div</span><span class="tag">></span><span>  </span></span></li><li class=""><span><span class="tag"><</span><span class="tag-name">div</span><span> </span><span class="attribute">class</span><span>=</span><span class="attribute-value">"field"</span><span class="tag">></span><span>This is field 2</span><span class="tag"></</span><span class="tag-name">div</span><span class="tag">></span><span>  </span></span></li><li class="alt"><span><span class="tag"><</span><span class="tag-name">div</span><span> </span><span class="attribute">class</span><span>=</span><span class="attribute-value">"field"</span><span class="tag">></span><span>This is field 3</span><span class="tag"></</span><span class="tag-name">div</span><span class="tag">></span><span>  </span></span></li><li class=""><span><span class="tag"><</span><span class="tag-name">div</span><span> </span><span class="attribute">class</span><span>=</span><span class="attribute-value">"field"</span><span class="tag">></span><span>This is field 4</span><span class="tag"></</span><span class="tag-name">div</span><span class="tag">></span><span>  </span></span></li><li class="alt"><span><span class="tag"><</span><span class="tag-name">div</span><span> </span><span class="attribute">class</span><span>=</span><span class="attribute-value">"field"</span><span class="tag">></span><span>This is field 5</span><span class="tag"></</span><span class="tag-name">div</span><span class="tag">></span><span>  </span></span></li></ol></div><pre  title="code" class="xml"><div class="field">This is field 1</div>
<div class="field">This is field 2</div>
<div class="field">This is field 3</div>
<div class="field">This is field 4</div>
<div class="field">This is field 5</div>
</pre>
<br />All you have to do is a bit of jQuery manipulation to add all the ugly HTML back in. Like this...<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span>$(document).ready(</span><span class="keyword">function</span><span>() {  </span></span></li><li class=""><span>    $(<span class="string">'.field'</span><span>).before(</span><span class="string">'<div class="fieldOuter"><div class="inner">'</span><span>);  </span></span></li><li class="alt"><span>    $(<span class="string">'.field'</span><span>).after('</div><div </span><span class="keyword">class</span><span>=</span><span class="string">"errorBar"</span><span>><div </span><span class="keyword">class</span><span>=</span><span class="string">"icon"</span><span>>  </span></span></li><li class=""><span>        <img src=<span class="string" />"icon.png"</span><span> alt=</span><span class="string">"icon"</span><span> /></div><div </span><span class="keyword">class</span><span>=</span><span class="string">"message"</span><span>>  </span></span></li><li class="alt"><span>        <span>This is an error message</span></div></div></div>');  </span></li><li class=""><span>});  </span></li></ol></div><pre  title="code" class="Jscript">$(document).ready(function() {
    $('.field').before('<div class="fieldOuter"><div class="inner">');
    $('.field').after('</div><div class="errorBar"><div class="icon">
        <img src="icon.png" alt="icon" /></div><div class="message">
        <span>This is an error message</span></div></div></div>');
});
</pre>
<br />It's not always advisable to do this, you'll get a bit of a flash
as the page loads, but in certain situations where you've got a lot of
repeated HTML it can really reduce your page weight and the SEO
benefits of reducing all your repeated extraneous markup should be
obvious.<br /><br /><br /><br /><a name="tip17"></a>
<h3>17. Lazy load content for speed and SEO benefits</h3><br />
<br />Another way to speed up your page loads and neaten up the HTML that
search spiders see is to lazy load whole chunks of it using an AJAX
request after the rest of the page has loaded. The user can get
browsing right away and spiders only see the content you want them to
index.<br /><br />We've used this technique on our own site. Those purple
buttons at the top of the page drop down 3 forms, directions and a
google map, which was doubling the size of our pages. So, we just put
all that HTML in a static page and use the load() function to load it
in once the DOM was ready. Like this...<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span>$(</span><span class="string">'#forms'</span><span>).load(</span><span class="string">'content/headerForms.html'</span><span>, </span><span class="keyword">function</span><span>() {  </span></span></li><li class=""><span>    <span class="comment">// Code here runs once the content has loaded</span><span>  </span></span></li><li class="alt"><span>    <span class="comment">// Put all your event handlers etc. here.            </span><span>  </span></span></li><li class=""><span>});  </span></li></ol></div><pre  title="code" class="Jscript">$('#forms').load('content/headerForms.html', function() {
    // Code here runs once the content has loaded
    // Put all your event handlers etc. here.            
});
</pre>
<br />I wouldn't use this everywhere. You have to consider the trade offs
here. You're making extra requests to the server and portions of your
page might not be available to the user right away, but used correctly
it can be a great optimization technique.<br /><br /><br /><br /><a name="tip18"></a>
<h3>18. Use jQuery's utility functions</h3><br />
<br />jQuery isn't just about flash effects. The creator has exposed some
really useful methods which fill a few gaps in JavaScript's repertoire.<br /><br /><a href="http://docs.jquery.com/Utilities">http://docs.jquery.com/Utilities</a><br />
<br />In particular, browser support for certain common array functions
is patchy (IE7 doesn't even have an indexOf() method!). Jquery has
methods for iterating, filtering, cloning, merging and removing
duplicates from Arrays.<br /><br />Other common functions that are
difficult in Javascript include getting the selected item in a drop
down list. In plain old JavaScript you'd have to get the <select>
element using getElementByID, get the child elements as an array and
iterate through them checking whether each one was selected or not.
jQuery makes it easy...<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span>$(</span><span class="string">'#selectList'</span><span>).val();  </span></span></li></ol></div><pre  title="code" class="Jscript">$('#selectList').val();
</pre>
<br />It's worth spending some time looking through the jQuery
documentation on the main site and having a nose around some of the
lesser known functions.<br /><br /><br /><br /><a name="tip19"></a>
<h3>19. Use noconflict to rename the jquery object when using other frameworks</h3><br />
<br />Most javascript frameworks make use of the $ symbol as a shorthand
and this can cause clashes when trying to use more than one framework
on the same page. Luckily there's a simple solution. The .noconflict()
function gives control of the $ back and allows you to set your own
variable name, like this...<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span class="keyword">var</span><span> $j = jQuery.noConflict();  </span></span></li><li class=""><span>$j(<span class="string">'#myDiv'</span><span>).hide();  </span></span></li></ol></div><pre  title="code" class="Jscript">var $j = jQuery.noConflict();
$j('#myDiv').hide();
</pre>
<br /><br /><br /><a name="tip20"></a>
<h3>20. How to tell when images have loaded</h3><br />
<br />This is another one of those problems that doesn't seem to be as
well documented as it should be (not when I went looking anyway) and
it's a fairly common requirement when building photo galleries,
carousels etc, but it's fairly easy.<br /><br />All you have to do is use
the .load() method on an IMG element and put a callback function in it.
The following example changes the "src" attribute of an image tag to
load a new image and attaches a simple load function.<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span>$(</span><span class="string">'#myImage'</span><span>).attr(</span><span class="string">'src'</span><span>, </span><span class="string">'image.jpg'</span><span>).load(</span><span class="keyword">function</span><span>() {  </span></span></li><li class=""><span>    alert(<span class="string">'Image Loaded'</span><span>);  </span></span></li><li class="alt"><span>});  </span></li></ol></div><pre  title="code" class="Jscript">$('#myImage').attr('src', 'image.jpg').load(function() {
    alert('Image Loaded');
});
</pre>
<br />You should find that the alert is called as soon as the image is loaded.<br /><br /><br /><br /><a name="tip21"></a>
<h3>21. Always use the latest version</h3><br />
<br />jQuery is constantly improving and John Resig, it's creator, always seems to be in search of ways to improve performance.<br /><br />jQuery is currently on version 1.2.6 but John has already revealed that he's working on a new selector engine called <a href="http://ajaxian.com/archives/sizzle-john-resig-has-a-new-selector-engine">Sizzle</a>, which may apparently improve selector speeds in Firefox by up to 4x. So, it pays to keep up to date.<br /><br /><br /><br /><a name="tip22"></a>
<h3>22. How to check if an element exists</h3><br />
<br />You don't need to check if an element exists on the page before you
manipulate it because jQuery will will simply do nothing if you try to
select something and it isn't in the DOM. But when you do need to check
if anything has been selected, or how many items have been selected you
can use the length property.<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span class="keyword">if</span><span> ($('#myDiv).length) {  </span></span></li><li class=""><span>    <span class="comment">// your code</span><span>  </span></span></li><li class="alt"><span>}  </span></li></ol></div><pre  title="code" class="Jscript">if ($('#myDiv).length) {
    // your code
}
</pre>
<br />Simple, but not obvious.<br /><br /><br /><br /><a name="tip23"></a>
<h3>23. Add a JS class to your HTML attribute</h3><br />
<br />I learned this tip from Karl Swedberg whose <a href="http://www.amazon.co.uk/Learning-JQuery-Interaction-Development-Javascript/dp/1847192505/ref=sr_1_1?ie=UTF8&s=books&q>excellent</a> <a href="http://www.amazon.co.uk/JQuery-Reference-Guide-Karl-Swedberg/dp/1847193811/ref=sr_1_3?ie=UTF8&s=books&q>books</a> I used to learn jQuery.<br /><br />He recently left a comment on one of my previous articles about this technique and the basics are as follows...<br /><br />Firstly, as soon as jQuery has loaded you use it to add a "JS" class to your HTML tag.<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span>$(</span><span class="string">'HTML'</span><span>).addClass(</span><span class="string">'JS'</span><span>);  </span></span></li></ol></div><pre  title="code" class="Jscript">$('HTML').addClass('JS');
</pre>
<br />Because that only happens when javascript is enabled you can use it
to add CSS styles which only work if the user has JavaScript switched
on, like this...<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-css" start="1"><li class="alt"><span><span>.JS </span><span class="value">#myDiv</span><span>{</span><span class="keyword">display</span><span>:</span><span class="value">none</span><span>;}  </span></span></li></ol></div><pre  title="code" class="css">.JS #myDiv{display:none;}
</pre>
<br />So, what this means is that we can hide content when JavaScript is
switched on and then use jQuery to show it when necessary (e.g. by
collapsing some panels and expanding them when the user clicks on
them), while those with JavaScript off (and search engine spiders) see
all of the content as it's not hidden. I'll be using this one a lot in
the future.<br /><br />To read his full article <a href="http://www.learningjquery.com/2008/10/1-awesome-way-to-avoid-the-not-so-excellent-flash-of-amazing-unstyled-content">click here</a>.<br /><br /><br /><br /><a name="tip24"></a>
<h3>24. Return 'false' to prevent default behaviour</h3><br />
<br />This should be an obvious one but maybe not.  if you have a habit of doing this...<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-xml" start="1"><li class="alt"><span><span class="tag"><</span><span class="tag-name">a</span><span> </span><span class="attribute">href</span><span>=</span><span class="attribute-value">"#"</span><span> </span><span class="attribute">class</span><span>=</span><span class="attribute-value">"popup"</span><span class="tag">></span><span>Click me!</span><span class="tag"></</span><span class="tag-name">a</span><span class="tag">></span><span>  </span></span></li></ol></div><pre  title="code" class="xml"><a href="#" class="popup">Click me!</a>
</pre>
<br />... and then attaching an event handler like this...<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span>$(</span><span class="string">'popup'</span><span>).click(</span><span class="keyword">function</span><span>(){  </span></span></li><li class=""><span>    <span class="comment">// Launch popup code</span><span>  </span></span></li><li class="alt"><span>});  </span></li></ol></div><pre  title="code" class="Jscript">$('popup').click(function(){
    // Launch popup code
});
</pre>
<br />... it'll probably work fine until you use it on a long page, at
which point you'll notice that the # is causing it to jump to the top
of the page when your click event is triggered.<br /><br />All you have to
do to prevent this default behaviour, or indeed any default behaviour
on any event handler is to add "return false;" to your handler, like
this...<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span>$(</span><span class="string">'popup'</span><span>).click(</span><span class="keyword">function</span><span>(){  </span></span></li><li class=""><span>    <span class="comment">// Launch popup code</span><span>  </span></span></li><li class="alt"><span>    <span class="keyword">return</span><span> </span><span class="keyword">false</span><span>;  </span></span></li><li class=""><span>});  </span></li></ol></div><pre  title="code" class="Jscript">$('popup').click(function(){
    // Launch popup code
    return false;
});
</pre>
<br /><br /><a name="tip25"></a>
<br /><h3>25. Shorthand for the ready event</h3><br />
<br />A small tip this one but you can save a few characters by using shorthand for the $(document).ready function.<br /><br />Instead of this...<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span>$(document).ready(</span><span class="keyword">function</span><span> (){  </span></span></li><li class=""><span>    <span class="comment">// your code</span><span>  </span></span></li><li class="alt"><span>});  </span></li></ol></div><pre  title="code" class="Jscript">$(document).ready(function (){
    // your code
});
</pre>
<br />You can do this...<br /><br /><div class="dp-highlighter"><div class="bar"><div class="tools"><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('ViewSource',this);return false;">view plain</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('CopyToClipboard',this);return false;">copy to clipboard</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('PrintSource',this);return false;">print</a><a href="http://www.tvidesign.co.uk/blog/improve-your-jquery-25-excellent-tips.aspx#" onclick="dp.sh.Toolbar.Command('About',this);return false;">?</a></div></div><ol class="dp-c" start="1"><li class="alt"><span><span>$(</span><span class="keyword">function</span><span> (){  </span></span></li><li class=""><span>    <span class="comment">// your code</span><span>  </span></span></li><li class="alt"><span>});  </span></li></ol></div><pre  title="code" class="Jscript">$(function (){
    // your code
});
ry-25-excellent-tips.aspx