So the latest technical book I’ve been reading is Learning jQuery by Jonathan Chaffer and Karl Swedberg. The book is very interesting and comes packed with a bunch of neat little tricks that come in handy for a casual jQuery developer. With that said I decided to, again, get the most interesting parts and write them down for later referencing.

Unlike the book I am assuming all readers do know the basics of jQuery (thus, Javascript), so don’t expect to learn the whole thing here, and in case that’s what you were after then go search for some basic intro tutorials or buy the book. It’s worth mentioning that the book also treats about some more advanced topics such as creating shufflers, rotators, plugins, etc., but the main goal here is to be practical and know only enough necessary for our needs (thus, casual), anything above that we can always count on a number of plugins, some of which I’ll show in the end of the post.

For anyone willing to see any of the code that is being presented here in action, I created a small app separated into the same sections as the post containing the exact same code. Please forgive my poor design :)

Since this will be more of a reference guide (to myself and hopefully others) here’s a nice little quick-link menu:




The first and most basic thing we do on jQuery is supply a selector to the $() factory function with what we desire to manipulate, so let’s start simple with some of them:

$('#items > li:not(.sold)').addClass('highlight'); // will get all li elements directly descendant of the #items element that do NOT have the 'sold' class

$('a[href^=mailto:]').addClass('mailLink'); // will add an specific class for all links that start (^=) with 'mailto:'. The [] syntax works with any attribute;

$('a[href$=.pdf]').addClass('pdfLink'); // same as above, but gets all links ending ($=) with '.pdf'

$('tr:odd').addClass('odd'); // useful for alternating table rows, tr:even could also have been used.

$('td:contains(highlight)').addClass('highlight'); // will add the 'highlight' class to all td elements containight the 'highlight' text. This selector IS case sensitive.

$(':radio:checked').addClass('checked'); // easily handles checked radio buttons.

Apart from the selectors themselves, we have a method which works much like a selector, but holds the power of accepting a function and filtering results from the result of that function:

$('a.last').filter(function(){
	return this.hostname && this.hostname != location.hostname;
}).addClass('external');

The example above will return (and style) all links that have a domain name (excluding mailto links) and which hostnames are different than our current one, something impossible to do with the use of selectors alone.

Selectors Examples




Although holding immense power in them, selectors sometimes aren’t enough and we need some DOM traversal methods to give us this flexibility of going up and down the DOM tree:

$('td:contains(highlight)').next().addClass('highlight'); // will style the element right after the selected one

$('td:contains(highlight)').nextAll().addClass('highlight'); // will style ALL elements after the selected one

$('td:contains(highlight)').nextAll().andSelf().addClass('highlight'); // will style ALL elements after the selected one AND the selected one

The next() and nextAll() above have their counterparts prev() and prevAll(), behaving as you might expect.

We can also work with parents, children and siblings of an element:

$('#some-item').parent().addClass('highlight'); // will get the element right on top of the selected element in the DOM tree

$('#categories').children().addClass('highlight-blue'); // will get all elements that come below the selected element in the DOM tree

$('#products').children('.available').addClass('highlight-blue'); // you can optionally add a selector to be more specific on what you get back.

$('#posts').siblings().addClass('highlight-green'); // will get all elements in the same level as the selected element in the DOM tree. You can also add a selector here.

DOM Traversing Examples



Let’s move on to events, which allow us to respond to user interactions. In jQuery we handle events quite easily by doing what we call ‘binding’ a handler to an event on a certain element set (generated by a selector), so let’s take a look at a couple of compound method which can take two or more event handlers:

// will highlight on the first click, then go back to normal on the second, then highlight again on the third, and so on.
$('#item').toggle(function(){
	$(this).addClass('highlight');
}, function(){
	$(this).removeClass('highlight');
});
// this will achieve the same as above
$('#item').click(function(){
	$(this).toggleClass('highlight');
}); 

// will execute the first function when the mouse is over the element, and the second one when it leaves
$('#item2').hover(function(){
	$('#item2').addClass('highlight');
}, function(){
	$('#item2').removeClass('highlight');
});

We could also create our custom events and attach handlers to those, binding them through the use of bind() and triggering through the use of trigger() (somewhat obvious):

// assuming we have an outer fieldset with a bunch of text fields in it and a submit button 
$('fieldset').bind('verify', function(){
	$(this).children('input[type=text]').each(function(index,child){
		if ($(child).val().length > 5){
			$(child).addClass('highlight');
		}else{
			$(child).removeClass('highlight');
		}
	});
});
//notice how we can trigger our custom events through various ways
$('#submit').click(function(){
	$('fieldset').trigger('verify');
});
$('fieldset input[type=text]').keyup(function(){
	$('fieldset').trigger('verify');
});

To avoid getting caught in traps caused by event bubbling, we can either control the event target by manipulating the event object itself or by simply halting event propagation:

// assuming we have a button inside of another a div, we want to assure that the event only happens when we click on the div.
// first, using the event target
$('#outer').click(function(event){
	if (event.target == this) {
		$('#outer .button').toggleClass('hidden');
	}
});
// second, using the stopPropagation technique
$('#outer2').click(function(){
	alert('You clicked the div!');
});
$('#outer2 .button').click(function(event){
	alert('Button clicked!');
	event.stopPropagation();
});

Event delegation is a powerful technique that should be used as often as possible and we can achieve it by assigning an outer element an event handler and using the target attribute on the event to determine what should be done:

// assuming we have an outer #items div with alot of single items inside with ids like #item-34, #item-23, etc
$('#items').click(function(event){
	var foo = event.target.id.split('-')[0];
	if (foo == 'item'){
		alert('An item was clicked!');
	}
});
// of course we could use more simple ways to do this, but you get the catch: every item will report to the #items handler which will then decide what to do.

By making use of Javascript’s anonymous functions we can achieve some peculiar behavior with event handlers, such as binding and unbinding them at runtime by passing these functions as callbacks:

var alertHandler = function(){
	alert('hi');
}
$('#some-item').click(alertHandler);
$('#some-item .sub').click(function(){
	$('#some-item').unbind('click', alertHandler);
	$(this).addClass('highlight');
});
$('#restore').click(function(){
	$('#some-item').click(alertHandler);
};

Events Examples



Effects are one of the coolest parts in jQuery, with very little effort we can get some really eye-candy results. Starting some basic effect methods:

// the peculiar thing about hide() is that it remembers the display type (block, inline, etc) before turning it to 'none', whereas show() gets that remembered value and applies it back.
$('#button').toggle(function(){
	$('#div1').hide('slow');
	$('#div2').show('slow');
}, function(){
	$('#div2').hide('slow');
	$('#div1').show('slow');
});
// now with fading
$('#button2').toggle(function(){
	$('#div3').fadeOut('slow');
	$('#div4').fadeIn('slow');
}, function(){
	$('#div4').fadeOut('slow');
	$('#div3').fadeIn('slow');
});

Just like toggle() is a compound event handler, we have have slideToggle() (and most recently fadeToggle()) as a compount effects method:

$('#link').click(function(){
	$('#extra').slideToggle('slow');
});

Moving on to the farily complex animate() method (which I suggest you take a look at its documentation), we can chain a bunch of animations together and get one compound result or we can queue some so they happen in the order we specify:

// the single compount result
$('#animate').click(function(){
	$('#block').animate({height: '+=20px'}, 'slow')
	.animate({width: '+=5px'}, 'fast')
	.css('background-color', 'grey');
});
// queuing
$('#animate2').click(function(){
	$('#block2').animate({height: '+=20px'}, 'slow')
	.animate({width: '+=5px'}, 'fast')
	.queue(function(){
		$(this).css('background-color', 'grey')
		.dequeue();
	});
});
//now the coloring happens only after the width grows.

Another way we could achieve this queuing is by using callbacks on animate():

$('#animate3').click(function(){
	$('#block3').animate({height: '+=20px'}, 'slow')
	.animate({width: '+=5px'}, 'fast', function(){
		$('#block3').css('background-color', 'grey');
	});
});

Effects Examples




The book recommends a few very useful plugins that can handle alot of day-by-day tasks for us with quite an ease:

  • Form Plugin: makes form submition with AJAX extremely easy.
  • jQuery UI: a whole library of extremely cool widgets and interaction components.
  • Autocomplete: provides a list of possible matches as the user types in a text input.
  • Validation: a solution for client-side validation on forms.
  • Masked Input: makes it easy for users to enter data in specific formats, such as dates, phone numbers, etc.
  • Table Sorting: for client-side sorting of table data.
  • Jcrop: for client-side image cropping.
  • FancyBox: a cool way to add overlayed information to your page (instead of using pop-ups).
  • Highcharts: my personal recommendation, this is an awesome plugin for chart generation, giving you tons of options and a well spread documentation. In fact, I even recommend you taking a look at its demo page just for kicks.

As for other parts of the jQuery API such as DOM manipulation and AJAX support, there wasn’t anything thats stands out enough to be worth a mention, a quick read on the documentation should be enough since all DOM manipulation methods and the standard $.ajax() method are pretty straight forward. Also, if you happen to be a Rails developer, these 2 subjects are abstracted by the use of remote form tags and RJS templates, so in most cases you wouldn’t even need to look into the jQuery documentation for this anyway.

That’s about it folks, if you have any other tips worth pointing out for us casual jQuery devs please comment. Cheers!

About these ads