This is the first in a series of posts on browser-based development with Dojo. These were originally intended for the Bloglines team, but I thought I’d throw them out to a larger audience. I’ll try to keep the entries short, but no promises. Some things just need lots of explanation… Anyway, here’s the first and it’s on the event life cycle for a page.
When an HTML page loads (and unloads) a number of events fire allowing the application to do different things. Browsers tend to fire the following events:
- window.onload
- fires when the page has finished loading. This includes loading any external resources referenced by the HTML, like stylesheets, script, and images, both tags and images referenced by background: rules in CSS.
- window.onunload
- fires when the user navigates away from the page. This one is provided to give your script the ability to do stuff that needs to happen when the user leaves, like save state or cleanup outstanding XHRs. This event also tends to like to terminate execution after a set amount of time, so anything you do in here has to happen fast. Your script may not run to completion, depending on how long you’re taking and which browser you’re on. I don’t recall the limits off-hand, but they do vary.
In addition, some browsers expose a method for determining when the DOM is done being constructed, but images and such have not finished loading. Firefox calls this onDOMContentLoaded and there are hacks to get it supported on other browsers. This is really handy; when you’re pulling content from edge cached locations you don’t want to wait for all those locations to answer DNS and respond before you can get on with setting up your page and responding to user events.
Now, why wait for onLoad at all before running script? Well, the DOM is in an indeterminate state beforehand. Sure, you can setup an interval and query for things, but it’s generally safer to just wait for the browser to tell you everything is ok and then go on your way.
Dojo wraps up some of the hacks referenced above and exposes them as dojo.addOnLoad(). If you want something to happen when the browser is all set, just add it like this:
Definitely do not do the following:
This will whack any event handlers stuck onto onload (including Dojo’s) and nothing based on onLoad will work. A similar warning applies to onUnload. Don’t go trying to window.onunload = myAwesomeCleanupFunction. Dojo does some cleanup work in unload that we really want to keep around to keep IE from leaking like a sieve.
So, you may be wondering, what kinds of things would I want to dojo.addOnLoad()? How do I sync up all these things if there are dependencies between them? For Bloglines, we try to funnel everything init related through the main class for the page, which for /b/view is an instantiation of bl.page.view. bl.page.view hooks onto Dojo’s onLoad and does a whole bunch of work in bl.page.view.init. Instead of trying to hook all the independent parts of the application up to Dojo’s onLoad, we let init take care of all the lovely synchronization issues. That.. mostly works.
So with all this work going on in init, what happens to the browser? More on that and the wonderful single-threaded, message-based world of DOM development in the next installment.