YAPS: IE 6, body onload, 'n U

by Lisa Nicholls Sun, May 18 2008 20:37

I've decided I should have a blog category called "YAPS" (Yet Another PostScript), for all the times when I post and then think of something more I want to say to clarify on the subject later. This one clarifies http://www.spacefold.com/lisa/post/Anchors-Aweigh%2c-Away.aspx.

It turns out that under some very specific circumstances IE 6 isn't calling the body onload function, which is the logical place to put the navCheck function I discussed in that blog post.  It's not due to anything specific in my javascript; you can see the same behavior with anything in the body onload, for any page on which this occurs.

It actually works fine on Spacefold Articles, even in IE 6. So I suspect seeing the issue requires having a code-behind page, in your master page (because the SpacefoldArticles.Master file doesn't).  It might also require having a Page_Load function in that code-behind page.  Maybe ASP.NET handling either pre-empts the onload, or doesn't piggyback on it correctly from IE 6's POV, or just does something else in the wrong sequence, in this situation. 

Oh wait -- it may depend on your current DOCTYPE, too, because IE 6 is finicky about what it does and how it complies with standards (or doesn't) depending on DOCTYPE.  My DOCTYPE declaration for the "problem page" happens to be:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 1.0 Transitional//EN"

Whatever.  I've seen a lot of people point to mysterious failures of body onload in IE 6.  Here is an example.  There's a broad range of descriptions and observations of the failures.  Just type "body onload ie 6" in the search engine of your choice, and you'll doubtless see.

So here's my resolution: take the javascript out of the onload call, just don't use that event. Rather than getting fancy with adding events or figuring out whatever messiness the ASP.NET sequence is causing "behind the scenes"...  call the same script after all relevant elements in the page have been rendered, directly in the body of the page. 

In my case, that means that the master page finishes up like this:

<!-- more here -->
<asp:ContentPlaceHolder ID="MainContentArea" runat="server">
  <!-- Bottom Information Area -->
  <div id="BottomArea">
<!-- run the script after all the elements are defined -->

If you're not trying to access items on the page, you can probably put it somewhere more intuitive in the body, but (as you may remember from the original post), the navCheck() function is going to try to find an element on the page, using document.getElementById, and jump to that element if it's found.  So all the page elements have to be prepared and available, before this script actually runs.

Is that better than a plan?

Seems to work... in FireFox, Opera, IE, and Safari.

Weird, huh?