Here's 10 tips that will makes you code more efficiently with jQuery.
// Don't
if ($('#item').get(0)) {
$('#item').someFunction();
}
// Or
if ($('#item').length) {
$('#item').someFunction();
}
// Just do
$('#item').someFunction();
jQuery will call the function only if there is a match, no need to double check.
// You can but..
$(document).ready(function(){
// ...
});
// There is a shorter equivalent
$(function(){
// ...
});
It should be well known, but obviously it is not.
// Don't
$('#frame').fadeIn();
$('#frame .title').show();
$('#frame a:visited').hide;
// Do
$('#frame').fadeIn()
.find('.title').show().end()
.find('a:visited').hide();
Unnecessary DOM traversal is a expensive operation, avoid it when possible.
// Ugly
$('div.close').click(closeCallback);
$('button.close').click(closeCallback);
$('input.close').click(closeCallback);
// Not ugly
$('div.close, button.close, input.close')
.click(closeCallback);
// Don't
$('#nav li').click(function(){
$('#nav li').removeClass('active');
$(this).addClass('active');
});
// Do
$('#nav li').click(function(){
$(this).addClass('active')
.siblings().removeClass('active');
});
// Try to avoid
var output = [];
for (var i=0;i < arr.length; i++) {
output.push(arr[i]);
}
// Do
var output = $.map(arr, function() {
...
});
// Or
var output = [];
$.each(arr, function(index, value) {
output.push(value);
});
Using jQuery's each and map is more reliable because they won't break if another library is extending the Array object.
Events can be namespaced
$('input').bind('blur.validation', function(e){
// ...
});
The data method also accept namespaces
$('input').data('validation.isValid', true);
Instead of
var refreshFrame = function() {
$('#frame').load('http://reddit.com');
};
$('.button').click(refreshFrame);
refreshFrame();
You can do
$('.button').click(function() {
$('#frame').load('/page/frame.html');
}).triggerHandler('click');
// You can also use a shortcut
$('.button').click(function() {
$('#frame').load('/page/frame.html');
}).click();
triggerHandler is also useful for creating custom events, which leads me to my next tip
In some situation it can saves you lots of pain, it's also really handy to encapsulate plugins interactions. Let me illustrate.
$('.button').click(function() {
$('div#frame').load('/page/frame.html', function(){
$(this).triggerHandler('frameLoaded');
});
});
// PluginA.js
$('#frame').bind('frameLoaded', function(){
$(this).show('slide', {direction: 'top'});
});
// PluginB.js
$('div').bind('frameLoaded', function(){
// do something else
});
jQuery comes with a nice unit test framework called QUnit. Writing tests is quite easy and allow you to confidently modify your code while ensuring that it still works as expected.
module("A simple test");
test("The frame should appear #button is clicked", function() {
expect(1);
$('#button').click();
ok($('#frame').is(':visible'), "The frame is visible" );
});
Sorry comments are temporarely disabled... ps: fuck you blog spammers.
Nice list of tips. Some of them were new to me.
For the 5th point, isn't it more effective to save the active element to a global variable and deactivate just that one instead of all siblings?
Regarding the 6th point, isn't it a waste of memory and time to use the jquery-based iterations, when you can do that with the for loop? Especially, when it's all about simple going through each element in an array. What do you win avoiding normal for loops?
Good list. The only thing I would add, is to change #2, in order to prevent conflicts with $, to:
jQuery(function($){ ... }
I can tell #4 is going to be a tough one to remember for me. Great list, thanks for the post.
#5 and #8 are truly amazing. Thanks for making them appear them so easy than they really are(for me, of course).
Thanks for this.
The #2 is great, I never seen this before.
whats the point in #7 (namespaces)? when would you use it?
@ernesto
Suppose two plugins bind a onclick event on a elements. If you don't use namespaces the last plugin to be loaded will override the first plugin's event callback.
Unbinding the click event will also cause the click event to be unbinded for both plugins.
Proper namespacing ensure that no conflict will happens and everything works as expected.
It also allow to bluk unbind events by namespace, which can be pretty useful.
I'm trying to be lazy but it's biting me:
Even if no match is found, myfile is loaded from the server. Easiest way to see this is with Firebug. Point load to a file that doesn't exist and watch how you get a 404 in the console.
@Daniel
I also noticed this inconsistent behavior with load. Why they decided to handle this situation like this is beyond my understanding, but you've peaked my curiosity. I will investigate that and maybe fill a bug report.
Thanks very much! This is just helping with making more 'beautiful' and smaller code. I like this smarter approach.