Using .each() and contexts
One really cool usage of .each is using it to verify existence of a block of html on the page. If you are including all your site's javascript on every page or have DOM blocks that are conditionally included, then using this technique can help to improve performance significantly and compartmentalize your code.
This is probably how you typically see jQuery code written: $(function() {
$("#my_block select").change(function() {
...
});
$("#my_block a:contains('edit')".click(function() {
...
});
});
$(function() {
$("#my_block").each(function() {
$("#my_block select").change(function() {
...
});
$("#my_block a:contains('edit')").click(function() {
...
});
});
}); In this example, we are now able to use the id of the block by itself, which allows jQuery to use the browser's built in and very fast getElementById function to look up the block. It also prevents any of the other selectors from running if the block does not exist. Writing it this way also gives us another benefit. We now have the raw DOM object of the block available to use as a context for other searches. In case you aren't familiar with contexts in jQuery, it allows you to pass in a raw DOM object (not a jQuery object!) to use as the root node for the search. Typically when you run a selector, it searches the entire document for matches. Providing a context will restrict the search to the node you pass in. Be careful though, because if the context doesn't exist or is null then it will search the entire document tree. Contexts work well with .each because we are guaranteed that it will actually exist. If nothing matches the selector, then the anonymous function inside will not fire. Putting it all together would look something like this. $(function() {
$("#my_block").each(function() {
var my_block = this;
$("select", my_block).change(function() {
...
});
$("a:contains('edit')", my_block).click(function() {
...
});
});
}); Once more nice thing about this is that it leaves you poised to move the code into an application specific jQuery plugin. You can basically take the content of it out and call it on your block. (function($) {
$.fn.extend({
myBlockBehavior: function() {
return this.each(function() {
var my_block = this;
$("select", my_block).change(function() {
...
});
$("a:contains('edit')", my_block).click(function() {
...
});
});
}
});
})(jQuery);
$(function() {
$("#my_block").myBlockBehavior();
}); And now you have some clean, fast, encapsulated code that you can easily reuse.