picknick picknick - 12 days ago 5
HTML Question

Can I run javascript before the whole page is loaded?

I want to run a bit of javascript before the whole page has loaded. Is this possible? Or does the code start to execute on

</html>
?

Answer

Not only can you, but you have to make a special effort not to if you don't want to. :-)

When the browser encounters a script tag when parsing the HTML, it stops parsing and hands over to the Javascript interpreter, which runs the script. Only when the script is complete does the browser resume parsing the page (because the script might do document.write calls to output markup that the parser should handle). This is the default behavior; there are script tag attributes that can prevent this (defer and async).

So consider this:

<!DOCTYPE HTML>
<html><head><!-- yada yada yada --></head>
<body>
<p>Line 1</p>
<script type='text/javascript'>
    alert("Stop that parsing!");
</script>
<p>Line two</p>
</body>
</html>

If you load that page, you'll see the "Line 1" paragraph while the alert is showing, and the the "Line 2" paragraph appears after it's done.

Where it gets a bit tricky is interacting with the DOM, since the DOM is built up by the parser as it's doing its thing and your script may run before the DOM is completely ready to be manipulated. In general, if you only access elements that precede the script tag in the file, you're fine, but to be safe it's best to put off any DOM interactions until the DOM is fully built.

But for the most part, you can happily access the earlier elements. Consider:

<!DOCTYPE HTML>
<html><head><!-- yada yada yada --></head>
<body>
<p id='p1'>Line 1</p>
<script type='text/javascript'>
    document.write("<p>p1 is null? " + (document.getElementById('p1') == null ? "yes" : "no") + "</p>");
    document.write("<p>p2 is null? " + (document.getElementById('p2') == null ? "yes" : "no") + "</p>");
</script>
<p id='p2'>Line two</p>
</body>
</html>

The output you see is:

Line 1
p1 is null? false
p2 is null? true
Line 2

...because p1 exists as of when the script runs, but p2 doesn't.

I don't have a link handy, but In this message, the developers of the Google Closure library say that they don't see any big value to the "ready" style events that Prototype, jQuery, ExtJS, Dojo, and most others provide because if you put the script after the elements you want to interact with, you're fine; which falls in line with YUI's recommendation that you just put your scripts right before the closing </html> tag (since you have to put them somewhere, after all, and down there they don't hold up your page display). Now, personally, I do see some value in those events although I think they're over-used, but my point is that clearly you can start interacting with things very early on.