July 6, 2010

Load JavaScript Files Dynamically Using Prototype Framework

At times you may want to load JavaScript dynamically after the page is loaded. Selective, dynamic or lazy loading of JavaScript files can help you:

  • Decrease the initial (or total) download size of page
  • Increase the download performance of page
  • Increase the rendering performance of page
  • Organize your code in logical ways

You can do so via native JavaScript functions, yes, but if you are using a JavaScript framework such as Prototype, things become a whole lot easier.

Prerequisites

The following examples assumes that your page contains a <head> section which contains a reference to the Prototype JavaScript Framework. You can hotlink version 1.6.x of the framework from Google AJAX API content distribution network. To do so, add the following line in the head section of the page:

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/prototype/1.6/prototype.js"></script>

Example 1: Loading JavaScript File

The following example shows the basics of loading a JavaScript file via Prototype. For this, we will create a <script> element and append it to the document head. The script loaded in this way is executed as soon as it is loaded.

<p><a class="a2a_dd" href="http://www.addtoany.com/share_save">Bookmark</a></p>
<script type="text/javascript">
  document.observe("dom:loaded", function () {
    $$("head")[0].insert(new Element("script", {
      type: "text/javascript",
      src: "http://static.addtoany.com/menu/page.js"
    }));
  });
</script>

The script demonstrated in this example is the addtoany share button script. This script is inherently unobstructive; when loaded, it adds the addtoany share/save menu to all document elements with class a2a_dd.

Example 2: Loading JavaScript File On-Demand

The following example shows how to load a JavaScript file in response to an event – document ready, window load or button click for example. For this, we will wrap the code that loads the script inside an event handler.

<p><input type="button" value="Load Google Translate Element" id="button1"/></p>
<div id="google_translate_element"></div>
<script type="text/javascript">
  function googleTranslateElementInit() {
    new google.translate.TranslateElement({
      pageLanguage: "en"
    }, "google_translate_element");
  }
  document.observe("dom:loaded", function () {
    $("button1").observe("click", function (event) {
      this.disable();
      $$("head")[0].insert(new Element("script", {
        type: "text/javascript",
        src: "http://translate.google.com/translate_a/element.js?cb=googleTranslateElementInit"
      }));
    });
  });
</script>

The script demonstrated in this example is the Google's website translator script and it is loaded when the user clicks a button. The script requires us to create a callback function and specify its name in the query string. We fulfil this requirement by creating a function called googleTranslateElementInit in the global scope. This function is called internally by the script when it is loaded.

Example 3: Loading JavaScript File and Polling for Symbol

The following example addresses a very common requirement when you are loading JavaScript files dynamically: determine if the script has loaded before attempting to use it. Some, but not all browsers provide events that fire when a script is loaded. A more portable solution is to load the script and watch for the presence of a symbol – a variable or a function for example – that is defined inside the file we are loading. Prototype provides a PeriodicalExecuter utility that allows you to execute a function at specified intervals. We will use it to poll for the presence of the symbol.

<script type="text/javascript">
  document.observe("dom:loaded", function () {
    $$("head")[0].insert(new Element("script", {
      type: "text/javascript",
      src: "http://ajax.googleapis.com/ajax/libs/swfobject/2/swfobject.js"
    }));
    new PeriodicalExecuter(function (pe) {
      if (typeof swfobject != "undefined") {
        pe.stop();
        var flashPlayerVersion = swfobject.getFlashPlayerVersion();
        alert("swfobject reports that your installed Flash Player version is " + flashPlayerVersion.major + "." + flashPlayerVersion.minor + "." + flashPlayerVersion.release);
      }
    }, 1);
  });
</script>

The script demonstrated in this example is the SWFObject script. SWFObject library exposes a variable called swfobject. In this example we load the SWFObject library and poll for the presence of this variable at regular intervals using the PeriodicalExecuter utility and typeof operator.

Notes

  • You will notice that various fragments of example code are wrapped inside document.observe("dom:loaded", function () {...});. This is not necessary but a recommended practice.
  • Examples shown here are based on Prototype JavaScript Framework; however, it is fairly easy to map them to other JavaScript frameworks such as jQuery.

Recommended Reading