9.2 Initiating a Process After the Page Loads

NN 2, IE 3

9.2.1 Problem

When a new page loads into the browser, you want to execute script statements requiring that all content, including images and plug-ins or ActiveX controls, be loaded and ready to go.

9.2.2 Solution

The onload event of the window object fires after all content and processes coded in the HTML have finished loading and self-initializing. Use this event to trigger the function(s) needed to complete the initialization of your scripted objects. All scriptable browsers support the following syntax:

<body onload="myInitFunction( )"> ... </body>

All browsers back to Navigator 3 and Internet Explorer 4 support the following script syntax, which may be included in a script located in the head portion of the document:

window.onload = myInitFunction;

In this latter case, make sure the myInitFunction( ) is defined earlier in the script code than the event assignment statement.

9.2.3 Discussion

Many recipes of this book include one or more initialization functions invoked by the onload event handler. My preference is to place the onload event handler as an attribute of the body element. It is always easy to find when editing and maintaining the code, and it's usually near the scripts, as well. If I need multiple initializations, such as the DHTML API library of Recipe 13.3 plus some other module, I can combine the initializations in the optimum sequence (in case one relies on another), as in:

<body onload="initDHTMLAPI( ); setHeights( )">

Event binding via property assignment does not allow multiple function assignments to the same event. If you include a second statement for the same object and event, it overrides the first. Therefore, if you need multiple functions initialized for window.onload, direct the event to fire a dispatcher-like function that then invokes each of your detailed initialization functions in the desired sequence:

function startup( ) {
    initDHTMLAPI( );
    setHeights( );
window.onload = startup;

Initializing event handlers after the document has loaded brings you and your users one extra benefit: events do nothing until all of the page's content is loaded into the browser. This is especially helpful if your page includes scripts that communicate with plug-ins or ActiveX controls. If a user clicks on a button that triggers a script before the ancillary machinery is in place, script errors will occur.

Using the onload event handler as a trigger for scripted event binding offers some intriguing benefits. First of all, you automatically assure that very old browsers won't respond to events because they don't understand the event name properties. The result is that you filter out browsers that choke on function handlers intended for more modern browsers. Second, you can filter out even more browsers with the help of object detection. For example, if you wish to limit event function access to browsers that support the basic W3C DOM element object reference syntax, you can surround the event assignment statements by conditional statements that validate browser support for your requirements:

function initEvents( ) {
    // these events OK with all but NN2 and IE3
    document.forms[0].onsubmit = validateMainForm;
    document.forms[0].elements["email"].onchange = validateEmail;
    if (document.getElementById) {
        // these work only in when W3C DOM supported
        document.getElementById("logo").onclick = goHome;
        document.body.onclick = blockEvent;
window.onload = initEvents;

This approach is far superior to wrapping script statement blocks in <script> tags that define the JavaScript version through the language attribute (e.g., language="JavaScript1.2"). Using the core JavaScript language versions as a predictor of things such as document object model version and support is foolhardy. Use object detection instead.

9.2.4 See Also

The Discussion in Recipe 9.1 on event binding types.