How To Code A Cross-Browser Script Dom Onload Event Handler?

Published On: 12 Feb, 2015 Updated On: 21 Apr, 2017

In this blog post, we’re going to learn in step-by-step how to create a beautiful JavaScript function which accepts a JavaScript resource url, target element and a callback and then creates a script dom object, registers callback function and at the end appends it to target dom element.

Before we start any further, it’s very important to understand how modern browsers work. I will discuss the concepts in brief. Stupendous information can be found at: Behind the scenes of modern web browsers - HTML5 Rocks.

How Modern Browsers Work ?

When a url is entered into the address box of the browser and hit Go button, the rendering engine of the browser starts downloading the contents of the given url through Network layer. Internally, every browser implements a tokenizer which plays an important role in tokenizing incoming HTML elements and deciding different paths for different type of DOM elements. As soon as the content is downloaded and available, the tokenizer sends tokens to HTML/CSS/JavaScript parsers based on the type of DOM element.

Rendering engine will take help of HTML parser to construct a tree of DOM elements called “content tree”. With the help of CSS parser, rendering engine will collect style information. Now, rendering engine constructs another tree called “render tree” which is a collection of DOM nodes with styles assigned to them.

Once “render tree” is constructed, document is declared to be interactive, with “document” as its root node. At this stage, the document’s state is set to “complete” and it’s “load” event is fired. In general, this is called as “document ready” event.

Next is the “layout stage” where each node of the render tree is given specific co-ordinates where they should be rendered. And then, the data is passed to “painting stage”. At this time, the document is rendered visually. Behind the scenes, the painting is handled by UI backend interface which is platform independant. Internally, it uses operating system’s user interface methods to draw all those DOM boxes.

How Browsers Read And Execute JavaScript ?

Now, as we have basic idea of how browsers work, it’s time to dive little deeper. Remember how “render tree” is constructed ? Good. Let’s imagine the tokenizer encountered a <script> tag (A generic script tag without “defer” or “async” attributes). Tokenizer sends it to JavaScript parser. JavaScript parser sends http request to download the content of provided url. Once content is obtained, it’s parsed/compiled and then executed. Modern browsers have that capability to compile few of the code statements and convert them into machine code.

Let’s say that your script is referring to an element which comes after the script tag in the document. If, at this time, your script gets executed, you’ll get errors in console. Do you know why ? It’s because, the “render tree” is still in construction phase and the document is not yet interactive. Elements that you’re referring are not yet available in “render tree”, hence throws the errors.

Writing Cross-Browser Script Dom Onload Event Handler

Alright. Now we know how browsers load and execute JavaScript. But sometimes we don’t want to just download the javascript files on-the-fly, but also want to perform some tasks like calling callback functions once resources are downloaded.

So, below written code takes care of calling callback function when any JavaScript resources are loaded on-the-fly.

Using Pure JavaScript


// Create script dom object
var scriptDom = document.createElement('script');

// Set its type. Not required if your DOCTYPE is HTML5
scriptDom.type = 'text/javascript';

// Set script dom's resource url
scriptDom.src = 'http://www.domain.com/abc/xyz.js';

/*
 * Set script dom's onload callback
 * For now, lets imagine 'onloadCallback' as a variable 
 * referrencing some anonymous function which handles script onload tasks.
*/
if (scriptDom.addEventListener) {
  scriptDom.addEventListener('load', onloadCallback, false);
}
else if(scriptDom.attachEvent) {
  scriptDom.attachEvent('onload', onloadCallback);
}
else {
  scriptDom.onload = onloadCallback;
}

/*
 * Finally append it wherever you like. Here, it's appended to the body.
 * Appending script dom object should be done only after onload callback is assigned.
 * Otherwise, onload callback will not work.
*/
document.body.appendChild(scriptDom);

Unfortunately, above code doesn’t work in older browsers like Internet Explorer 8. Reason is, Internet Explorer 8 doesn’t have “.onload” method for script dom object. If you enter “typeof scriptDom.onload” in the console and hit enter, it prints “undefined”.

Nothing to worry. We’ve IE 8 specific script dom onload event handler code too :-


if (scriptDom.attachEvent) {
  scriptDom.onreadystatechange = function() {
    if (scriptDom.readyState === 'loaded' || scriptDom.readyState === 'complete') {
      // write code that executes, once the javascript resource gets loaded
    }
  };
}

Putting it all together and wrapping it inside a function :-


var generateAndAppendScriptDomObject = function(srcUrl, callback, targetDomElem) {
  var scriptDom = document.createElement('script');
  scriptDom.type = 'text/javascript';
  scriptDom.src = srcUrl;

  if (scriptDom.addEventListener) {
    scriptDom.addEventListener('load', callback, false);
  }
  else if (scriptDom.attachEvent) {
    scriptDom.onreadystatechange = function() {
      if (scriptDom.readyState === 'loaded' || scriptDom.readyState === 'complete') {
        callback();
      }
    };
  }
  else {
    scriptDom.onload = callback;
  }

  /*
   * Considering 'targetDomElem' as some Dom Object 
   * ( say targetDomElem = document.getElementById('abc') Or targetDomElem = document.body ).
  */
  targetDomElem.appendChild(scriptDom);
};

Perfect! That’s it. This is a perfect cross-browser solution for our problem using pure JavaScript. There is another way, same functionality can be achieved using jQuery.

Using jQuery

jQuery as of version 1.0 has in-built function called $.getScript. This function uses ajax calls to load given javascript resource and on success, can call custom callbacks. If your website already has jquery required version pre-loaded, then you can use this function.

$.getScript can be used to download not only javascript but any kind of resources.

Brief snippet ( Taken from jQuery.getScript API Documentation ):-


$.getScript( "ajax/test.js" )
  .done(function( script, textStatus ) {
    console.log( textStatus );
  })
  .fail(function( jqxhr, settings, exception ) {
    $( "div.log" ).text( "Triggered ajaxError handler." );
});

By default, $.getScript() sets the cache setting to false. Use below code prior to $.getScript in order to cache script resources :-

$.ajaxSetup({
  cache: true
});

Well. That’s all. Thanks for reading this blog. If you have any questions, please feel free to email me. And yes. You can post your comments too.

Like this blog ? Share it on your favourite social network.
Search powered by Google

Didn’t find what you were looking for? Try here.

Template Monster

Where you can search over 26K+ Premium Templates.

Now, get flat 10% discount by using “b3fbdxkv49mosrt59dsh0dx29” promo-code.

Email NewsLetter

By subscribing, you’ll get access to latest blogs and other resources. Also, whenever there is any new content addition here, you’ll receive those updates directly to your inbox.

NOTE: I’m a strict antispammer. So you don’t have to worry about spams.

This website is designed by keeping modern browsers in mind. Never mind about legacy browsers. It’s high time we upgrade ourselves.

The website and its contents are created, edited and maintained solely by me (Santosh K Shetty). No one else shall possess any kind of resources unless explicitely mentioned.

Some of the Creative Credit goes to FreePik.

Copyright © from Jun 2014 to May 2018

Table  Of  Contents
On this page,