Automate firing of onload events
I've often had to set up onload events that execute for only a single page. I've both hardcoded those function calls right into the markup and I've done page detection in a shared js file (parsing the current URL, ew!). Neither solution is rather pretty. The below solution keeps things unobtrusive.
Set up the body tag with an ID that identifies the page, such as:
<body id="homepage">Over in your javascript, set up your page init code in an object literal:
var siteNameSpace = { homepage : { onload : function(){ // do this stuff. } }, contact : { onload : function(){ // onload stuff for contact us page } } };
Your document ready code executes for the same for all pages:
jQuery:
$(document).ready( siteNameSpace[ document.body.id ].onload );
Prototype:
Event.observe(window, 'load', siteNameSpace[ document.body.id ].onload );
YUI:
YAHOO.util.Event.onDOMReady( siteNameSpace[ document.body.id ].onload );
However this will fail if that object (and onload function) are not defined.
But you can fix it with a little more code..
//jQuery version $(document).ready( function(){ var NS = window.siteNameSpace, bID = document.body.id; if(NS && NS[ bID ] && (typeof NS[ bID ].onload === 'function')){ NS[ bID ].onload(); } } );
Follow me on twitter: @paul_irish
The other benefit of this technique is that CSS developers also use the body#pagename technique to target specific pages.
I'm not quite sure what you mean by "page detection in a shared file", but I think my solution to this for a while is similar to your suggestion.
Basic difference is that I use a global onload function in my site namespace which always responds to the browser event, and then dispatches to a page specific onload handler if it exists (using the body ID). This gives me a hierarchy, and the opportunity to have global init code as well as page specific init code. (Yes, I name my functions 'init' instead of 'onload').
Our solutions are indeed unobtrusive and clean, no extra hookup code needed for each page, just the actual page specific code. Just remember to tell any CSS gurus not to change any body IDs on a whim :)
Haha, yup! Cool to hear you use the same technique.
I tend to use classes on the body to designate a particular page or section of the site rather than an ID. Using a class makes more sense to me because I'm often dealing with sets of pages, rather than a single unique page.
It seems to me that the same sort of solution could be adapted to key off of classes instead of the ID. You might be able to take this even further if a page was not a single type, but more of a blend of types. That way you could assign multiple classes to a page and encapsulate behavior to a particular class. Just add a new class to get some new behavior.
Matt, yeah classes work better if you're executing similar code on multiple pages. Good call there.
I like that approach.
Paul, this is a great idea.
Since Prototype 1.6 now supports DOMContentLoaded natively, one can use this line of code:
document.observe('dom:loaded', siteNameSpace[ document.body.id ].onload );
Paul I like your approach to segregating your onload events - it's definitely a great way to approach it because it can be framework neutral (as opposed to the way I go about it).
Will definitely be checking out your blog often. Hopefully we can meet up at the news M&SS meeting!
Good points. I agree and i think most intelligent people will.