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>?

Answers:

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. The parser doesn't continue until the script execution is complete (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 change that behavior (defer and async) (and because they change it, scripts loaded with defer or async cannot use document.write to output HTML to the page being loaded).

So consider this:

<p>Line 1</p>
<script>
    alert("Paragraphs: " + document.getElementsByTagName("p").length);
</script>
<p>Line 2</p>

If you load that page, the alert will show "Paragraphs: 1" because only one p element exists in the DOM at that point (the one containing "Line 1"). You may or may not see Line 1 in the browser display, depending on the browser, because even though the element is in the DOM, the browser may not have had time to render it yet (since alert brings the UI thread to screeching halt).

Some browsers are...adjusting...the behavior of alert, though. For instance, if you had that code in a page and opened it in a new tab in the background, recent versions of Chrome would allow the page to continue loading (and allow JavaScript code to keep running), and show the alert when you went to the tab, even though that's very different to the behavior when you encounter that alert when the tab is active.

Whether they've been rendered or not, you can happily access the earlier elements, which is why we saw "Paragraphs: 1" above. Here's another example:

<p id='p1'>Line 1</p>
<script>
    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 2</p>

The output you see is:

Line 1
p1 is null? no
p2 is null? yes
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.

Answer

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 the DOMContentLoaded event or functions like $.ready in jQuery.

Tags

Recent Questions

Top Questions

Home Tags Terms of Service Privacy Policy DMCA Contact Us

©2020 All rights reserved.