When are document elements available to scripts?

| 9 Comments

As far as I can tell, the DOM and HTML specifications are silient on the issue of when DOM elements become available to scripts embedded within the document. That is, if you have an element <div id="foo">, when can you call getElementById('foo') and be sure that you'll get a valid result?

To be safe, we typically wait for the onload() event. (Although the specifications don't explicitly guarantee that, either.) It appears to be common practice for browser vendors to make the DOM available while it is being parsed. That is, any script in the body of a document can access any elements that appear before it in the document.

Can anyone with more knowledge of the specifications, or with more experience writing production code comment on this issue?

This is, of course, related to the "onload problem" which Dean Edwards purports to have solved. In the comments to that post, Dean asserts that placing scripts at the very end of the body does not guarantee that those scripts will have access to the whole document. Dean's experience carries a lot of weight, but he does actually have code that demonstrates that this technique is unreliable.)

Comments are open.

9 Comments

I just tested it, and JavaScript can definitely access all elements that were defined before the script block. See http://www.quirksmode.org/available.html for my test page.

Even Netscape 3 and 4 score on the first test, which is the only one they can handle.

I believe you might want to widen the scope of the question a bit, too -- while you might be able to get read access to nodes prior to a completed page load, write access support varies among browsers. Mozilla has no problem with inlined scripts doing, for instance, document.body.appendChild(), whereas Internet Explorer (6, at least) will abort loading and rendering the page after that single instruction with a very cryptic error trail (occasionally not even getting that far), I noticed (http://ecmanaut.blogspot.com/2005/12/bugfixed-clustrmaps-tutorial-onload.html) in a tutorial of mine (http://ecmanaut.blogspot.com/2005/11/clustrmaps-inkblotch-visitor.html) I had not tested properly.

My comments regarding accessible elements are based on Internet Explorer. This is definitely not a reliable technique for that platform. It works most of the time but there are occassions when parts of the DOM are inaccessible. This won't show up in casual testing but in real-life production code you will get errors. This is most notable when clicking the back button or using document.write to generate content.

Thank you, ppk, Johan, and Dean! Dean: I'll see if I can duplicate the problems you encountered when returning to a page (like ppk's test page) with the Back button.

Using the element after it has been defined, but before onload works in all modern browsers. We've been using this for quite a while and it works in IE, Firefox, Opera and Safari.

If you're going to have to check manually, http://openjsan.org/doc/a/au/autarch/DOM/Ready/ looks useful, providing an onIdReady() function taking callback functions for when the element is ready.

There have been situations in which I had to use a small delay using setTimeout before I could access a previously defined element in Firefox 1.5. In previous versions of Firefox this code worked fine without the delay.

This was a production situation in a large page; I was not able to reproduce this in a simple testcase...

In Mozilla (i.e. the Gecko engine) there is the DOMContentLoaded event (it's written exactly that). It fires when the DOM tree just becomes accessible, but in most cases _before_ the page is finished rendering. Also, the event might fire _before_ (on)load, i.e. when deferred elements of the page are still loading (such as images and stylesheets).

DOMContentLoaded used to be an undocumented feature in Gecko, not sure about the current status of the documentation. It's a stable interface, though.

See http://www.themaninblue.com/writing/perspective/2006/01/19/ for an explanation of the IE problems. I'd forgotten this, but he's right.

Books

Comprehensive coverage of Ruby 1.8 and 1.9

"The New Most Important Ruby Book"
Peter Cooper,
rubyinside.com

Completely updated for Ajax and Web 2.0

"A must-have reference"
Brendan Eich,
creator of JavaScript

The classic Java quick-reference

Advertising

Pages

Hosted By

Powered by Movable Type 4.21-en