Monthly Archives: November 2011

Load jQuery on demand

In order to load jQuery on demand you can use loadJquery.js script.

Quick start

Download script, edit its bottom part after words “PUT YOUR CODE HERE”, this one:

(function () {

...

    /* -------------------- PUT YOUR CODE HERE ------------------ */
    loadJquery({
        url: 'http://code.jquery.com/jquery-latest.min.js',
        timeout: 5000, //ms
        success: function ($) {
            $('h1').css('border', '2px solid red');
        },
        error: function () {
            alert("Can't load jQuery.");
        }
    });
}());

Advantages:

  • based on jquery 1.7.2, so should be stable and cross-browser
  • exceptions handled with help of try/catch
  • ability to set download timeout
  • jQuery will not be loaded, if found in page
  • simplicity for end-user: just write your code in success/error callbacks
  • no conflicts with other javascript libraries like prototype.js
  • script passes jslint-validation

Now bit more information for those who interested.
Script consists of two parts: loadScript и loadJquery.

loadScript

The function almost completely based on jQuery 1.7.2, which is latest at the moment.
External script is loading by putting SCRIPT tag into HEAD.
Exceptions are handled with try/catch, in theory javascript-erorrs, if any, should be catched without placing error in browser console.
There is possibility to setup download timeout. If timeout reached, download will be stopped and error-callback will be called.

Example of using:

loadScript({
    url: 'http://example.com/script.js', //script url
    timeout: 5000, //optional timeout in ms
    success: function () {
        alert('Script loaded callback.');
    },
    error: function () {
        alert('Script was not loaded.');
    }
});

loadJquery

Few details about this function:

  • jQuery will not be loaded, if found in page
  • .noConflict() used, so end-user should not worry about conflicts with other javascript library like prototype.js

Full listing of the script.

/*!
 *
 * loadJquery.js
 * Load jQuery on demand from javascript
 * Author: contact@slicezilla.com
 * November 2011
 *
 * The script uses part of jQuery JavaScript Library v1.7
 * http://jquery.com/
 * Copyright 2011, John Resig
 * Dual licensed under the MIT or GPL Version 2 licenses.
 * http://jquery.org/license
 *
*/
/*global document, setTimeout, clearTimeout, alert, jQuery*/
(function () {
    "use strict";
    var loadScript = function (options) {
        var script, transportTimeout,
            head = document.head || document.getElementsByTagName('head')[0] || document.documentElement,
            transport = {
                send: function (url, successCallback) {

                    script = document.createElement('script');

                    script.async = 'async';
                    script.src = url;

                    // Attach handlers for all browsers
                    script.onload = script.onreadystatechange = function (event, isAbort) {
                        if (isAbort || !script.readyState || /loaded|complete/.test(script.readyState)) {

                            // Handle memory leak in IE
                            script.onload = script.onreadystatechange = null;

                            // Remove the script
                            if (head && script.parentNode) {
                                head.removeChild(script);
                            }

                            // Dereference the script
                            script = undefined;

                            //callback if not abort
                            if (!isAbort && typeof successCallback === 'function') {
                                clearTimeout(transportTimeout);
                                successCallback();
                            }
                        }
                    };
                    // Use insertBefore instead of appendChild  to circumvent an IE6 bug.
                    // This arises when a base node is used (#2709 and #4378).
                    head.insertBefore(script, head.firstChild);
                    //head.appendChild(script);
                },

                abort: function (errorCallback) {
                    clearTimeout(transportTimeout);
                    if (script) {
                        script.onload(0, 1);
                    }
                    if (typeof errorCallback === 'function') {
                        errorCallback();
                    }
                }
            };

        //init timeout
        if (options.timeout > 0) {
            transportTimeout = setTimeout(function () {
                transport.abort(options.error);
            }, options.timeout);
        }

        //get script
        try {
            transport.send(options.url, options.success);
        } catch (e) {
            transport.abort(options.error);
        }
    };

    //function which will load jQuery using loadScript
    function loadJquery(options) {
        if (typeof jQuery !== 'undefined') {
            //jQuery is loaded already, just perform business logic
            if (typeof options.success === 'function') {
                //pass jQuery as parameter, in order to have $ === jQuery in callback
                //just in case that $.noConflict was used already, and $ !== jQuery
                jQuery(options.success);
            }
        } else {
            //jQuery was not loaded on a page
            loadScript({
                url: options.url,
                timeout: options.timeout,
                success: function () {
                    jQuery.noConflict();
                    if (typeof options.success === 'function') {
                        jQuery(options.success);
                    }
                },
                error: options.error
            });
        }
    }

    /* -------------------- PUT YOUR CODE HERE ------------------ */
    loadJquery({
        url: 'http://code.jquery.com/jquery-latest.min.js',
        timeout: 5000, //ms
        success: function ($) {
            $('h1').css('border', '2px solid red');
        },
        error: function () {
            alert("Can't load jQuery.");
        }
    });

}());