32

Here is the circumstance: I have 2 pages:

  • 1 x html page
  • 1 x external Javascript

Now in the html page, there will be internal Javascript coding to allow the placement of the window.onload, and other page specific methods/functions.

But, in the external Javascript I want certain things to be done before the window.onload event is triggered. This is to allow customized components to be initialized first.

Is there a way to ensure initialization to occur in the external Javascript before the window.onload event is triggered?

The reason I have asked this, is to attempt to make reusable code (build once - use all over), to which the external script must check that it is in 'order/check' before the Javascript in the main html/jsp/asp/PHP page takes over. And also I am not looking for a solution in jQuery @_@

Here are some of the links on Stack Overflow I have browsed through for a solution:

Can someone help or direct me to a solution, your help will be muchness of greatness appreciated.


[updated response - 19 November 2012]

Hi all, thanks for you advice and suggested solutions, they have all been useful in the search and testing for a viable solution. Though I feel that I am not 100% satisfied with my own results, I know your advice and help has moved me closer to a solution, and may indeed aid others in a similar situation.

Here is what I have come up with:

test_page.html

<html>
<head>
<title></title>
<script type="text/javascript" src="loader.js"></script>
<script type="text/javascript" src="test_script_1.js"></script>
<script type="text/javascript" src="test_script_2.js"></script>
<script type="text/javascript">
window.onload = function() {
    document.getElementById("div_1").innerHTML = "window.onload complete!";
}
</script>

<style type="text/css">
div {
    border:thin solid #000000;
    width:500px;
}
</head>
<body>
    <div id="div_1"></div>

    <br/><br/>

    <div id="div_2"></div>

    <br/><br/>

    <div id="div_3"></div>
</body>
</html>

loader.js

var Loader = {
    methods_arr : [],

    init_Loader : new function() {
        document.onreadystatechange = function(e) {
            if (document.readyState == "complete") {
                for (var i = 0; i < Loader.methods_arr.length; i++) {
                    Loader.method_arr[i]();
                }
            }
        }
    },

    load : function(method) {
        Loader.methods_arr.push(method);
    }
}

test_script_1.js

Loader.load(function(){initTestScript1();});

function initTestScript1() {
    document.getElementById("div_1").innerHTML = "Test Script 1 Initialized!";
}

test_script_2.js

Loader.load(function(){initTestScript2();});

function initTestScript2() {
    document.getElementById("div_2").innerHTML = "Test Script 2 Initialized!";
}

This will ensure that scripts are invoked before invocation of the window.onload event handler, but also ensuring that the document is rendered first.

What do you think of this possible solution?

Thanking you all again for the aid and help :D

4 Answers 4

24

Basically, you're looking for this:

document.onreadystatechange = function(e)
{
    if (document.readyState === 'complete')
    {
        //dom is ready, window.onload fires later
    }
};
window.onload = function(e)
{
    //document.readyState will be complete, it's one of the requirements for the window.onload event to be fired
    //do stuff for when everything is loaded
};

see MDN for more details.

Do keep in mind that the DOM might be loaded here, but that doesn't mean that the external js file has been loaded, so you might not have access to all the functions/objects that are defined in that script. If you want to check for that, you'll have to use window.onload, to ensure that all external resources have been loaded, too.

So, basically, in your external script, you'll be needing 2 event handlers: one for the readystatechange, which does what you need to be done on DOMready, and a window.onload, which will, by definition, be fired after the document is ready. (this checks if the page is fully loaded).
Just so you know, in IE<9 window.onload causes a memory leak (because the DOM and the JScript engine are two separate entities, the window object never gets unloaded fully, and the listener isn't GC'ed). There is a way to fix this, which I've posted here, it's quite verbose, though, but just so you know...

1
  • Can somebody help me to understand this code, it's working when i used this. But I'am not fully understanding the code here. What part should be put inside the if condition and what part in window.onload = function(e) Commented May 18, 2020 at 8:40
4

If you want something to be done right away without waiting for any event then you can just do it in the JavaScript - you don't have to do anything for your code to run right away, just don't do anything that would make your code wait. So it's actually easier than waiting for events.

For example if you have this HTML:

<div id=one></div>
<script src="your-script.js"></script>
<div id=two></div>

then whatever code is in your-script.js will be run after the div with id=one but before the div with id=two is parsed. Just don't register event callbacks but do what you need right away in your JavaScript.

3

javascript runs from top to bottom. this means.. if you include your external javascript before your internal javascript it would simply run before the internal javascript runs.

5
  • 1
    Not entirely true: <script src="some/huge/script.js" async="async"></script><script>alert('foo');</script>: The internal script will run before the external file was loaded Commented Nov 7, 2012 at 13:13
  • 3
    true but people who use async DO know about that.
    – GottZ
    Commented Nov 7, 2012 at 13:28
  • I just wanted to point out that the top-to-bottom thing isn't always the case, for completeness. PS: assuming that ppl who use async know about that, could be a dangerous assumption to make: there are tons of questions here about ajax calls not setting some var, because they expect AJAX to work synchronously. Commented Nov 7, 2012 at 14:19
  • 4
    in my opinion people that think ajax should work syncronously should actually start learning javascript.
    – GottZ
    Commented Nov 7, 2012 at 15:19
  • 1
    IMO, most of the people who are (ab)using JavaScript should start learning JS :). On that, I agree with Douglas Crockford: JS is the worlds most misunderstood and underestimated language Commented Nov 7, 2012 at 16:30
3

It is also possible to use the DOMContentLoaded event of the Window interface.

addEventListener("DOMContentLoaded", function() {
    // Your code goes here
});

The above code is actually adding the event listener to the window object, though it's not qualified as window.addEventListener because the window object is also the global scope of JavaScript code in webpages.

DOMContentLoaded happens before load, when images and other parts of the webpage aren't still fully loaded. However, all the elements added to the DOM within the initial call stack are guaranteed to be already added to their parents prior to this event.

You can find the official documentation here.

Not the answer you're looking for? Browse other questions tagged or ask your own question.