emachine
emachine

Reputation: 1163

Check if jQuery is included

I'm making a couple widgets meant to be included either separately or as a pair and in no particular order. I'm making sure jQuery is loaded by using this script:

if (typeof jQuery == 'undefined') {
    //alert("about to load jquery");

    var esm_script_tag = document.createElement('script');
    esm_script_tag.setAttribute("type","text/javascript");
    esm_script_tag.setAttribute("src", "http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js")
    esm_script_tag.onload = main; // Run main() once jQuery has loaded

    esm_script_tag.onreadystatechange = function () { // Same thing but for IE
        if (this.readyState == 'complete' || this.readyState == 'loaded') main();
    }

    document.getElementsByTagName("head")[0].appendChild(es_script_tag);

}
else{

    main();
}

On one script it fires the function main() and on the other main2(). The problem is that once the first script is run it begins including jQuery. When the second is run jQuery is not loaded up yet but won't load it again to fire off the function main2().

Is there a better way to include jQuery? Is there a way for my widgets to check if jQuery is in the middle of being loaded and to hold until it's ready?

Thanks for any replies.

Upvotes: 3

Views: 1296

Answers (1)

Alexander Yezutov
Alexander Yezutov

Reputation: 3214

Of course, first of all you should consider using 3rd party libraries for dependencies managements. However, it could be the situation, when you want to include the raw code to each widget, so it could live without any additional prerequired references.

On jsfiddle I created an emulation of what you a trying to ask: http://jsfiddle.net/ayezutov/dvvKE/16/

The following code is using timeouts to emulate script loading delay:

setTimeout(function() {
        document.getElementsByTagName("head")[0].appendChild(esm_script_tag);
    }, Math.floor(Math.random(500)));

In production version this should be for sure written as in your code.

So, after a little refactoring the loading code was moved to a single function: http://jsfiddle.net/ayezutov/dvvKE/20/. The issue still remains, as you can notice:

Loading jQuery from script 1:
Loading jQuery from script 2:
Executing main script 1: 1.5.1
Executing main script 2: 1.5.2

The next step was to create a custom queue, which would enqueue all loading requests, which came after the jQuery loading has begun:

    if (!window.__jQueryLoadedQueue)
        window.__jQueryLoadedQueue = [loadCompleted];
    else
    {
      window.__jQueryLoadedQueue.push(loadCompleted);
    }

    var completeFunction = function(){
        for(var i = 0; i < window.__jQueryLoadedQueue.length; i++){
            window.__jQueryLoadedQueue[i]();
        }
        delete window.__jQueryLoadedQueue;
    }

As you can see ( http://jsfiddle.net/ayezutov/dvvKE/23/ ) now the scripts starts loading only once, while both complete functions are called.

Upvotes: 1

Related Questions