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>
?
views:
158answers:
3I think you'll get an error if you attempt to refer to a control that is in the BODY before the whole page is loaded.
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 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, personaly, I do see value in those events, but it just goes to illustrate when you can start interacting with things.
You can run javascript code at any time. AFAIK it is executed at the moment the browser reaches the <script> tag where it is in. But you cannot access elements that are not loaded yet.
So if you need access to elements, you should wait until the DOM is loaded (this does not mean the whole page is loaded, including images and stuff. It's only the structure of the document, which is loaded much earlier, so you usually won't notice a delay), using body's onload
or functions like $.ready
in jQuery.