Skip to content
Advertisement

Javascript – alternative for window.onload when loading code asynchronously

I have a calculator I’m integrating into my site. Normally, when on a page by itself, the calculator initializes with the following function

window.onload = function () {

/* Initializes calculator */

}

However, I’m loading this calculator to the page asynchronously when the user asks for it, and it’s not on the page by default. How do I initialize the calculator once it’s loaded onto the page asynchronously? The problem I have is that the window.onload = function () which initializes the calculator doesn’t work when I load the calculator to the page asynchronously, since the window.onload event has already occurred. What function should I use instead of window.onload to initialize the calculator when it’s brought to the page asynchronously?

// 1. Page loads
// 2. Calculator is brought to page asynchronously 
// 3. Code below executes to initialize the calculator

***something else*** = function () {

/* Initializes calculator */

}

Advertisement

Answer

Change your anonymous function assigned to onload from this…

window.onload = function() {
    // stuff
};

…to a named function that’s invoked directly or indirectly based on document.readyState, like this:

function initCalculator() {
    // stuff
}

if( document.readyState === 'loading' ) {
    document.addEventListener( 'DOMContentLoaded', initCalculator );
}
else if( document.readyState === 'interactive' || document.readyState === 'complete' ) {
    initCalculator ();
}

  • If the <script> is part of the normal (static) HTML’s <head> and loaded synchronously or uses defer then the initCalculator function will run when 'DOMContentLoaded' fires.
  • If the <script> is part of the normal (static) HTML’s <head> with async – or the <script> was added after the page was loaded then the initCalculator function will run immediately if the async script was loaded after the DOMContentLoaded, or if it loads before DOMContentLoaded then it will run as appropriate.

To be extra-safe, you can prevent double-initialization by using a dataset entry on <html> (this is safer than adding a property on window):

function initCalculator() {
    if( document.documentElement.dataset['calcLoaded'] === 'true' ) return;
    
    // do stuff

    document.documentElement.dataset['calcLoaded'] = 'true';
}

if( document.readyState === 'loading' ) {
    document.addEventListener( 'DOMContentLoaded', initCalculator );
}
else if( document.readyState === 'interactive' || document.readyState === 'complete' ) {
    initCalculator ();
}
User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement