/    Sign up×
Community /Pin to ProfileBookmark

Loading Scripts in Specific Order

Hello,

I just got into javascript and need a bit of help dealing with a script im working on. The script relies on two javascript libraries to be loaded prior to me loading my own script. I’ve done some testing and for some reason it still shows in this order.

1 – My Script loaded
2 – jQuery UI loaded
3 – jQuery loaded

Yet I want it in this order so that jQuery & jQuery UI would offer their functionality to my script. The script should load in this order.

1 – jQuery
2 – jQuery UI
3 – My Script

This order is exactly the reverse of what i need. Any help would be greatly appreciated. Here is my code below.

[CODE]
loadjQuery();

function loadjQuery(){
head=document.getElementsByTagName(‘head’)[0];
var jqs=document.createElement(‘script’);
jqs.setAttribute(‘type’,’text/javascript’);
jqs.setAttribute(‘src’,’jquery-1.3.2.min.js’);
head.appendChild(jqs);
jqs.onload = loadjQueryUI();
jqs.onload = console.log(‘jQuery Loaded’);
}

function loadjQueryUI(){
head=document.getElementsByTagName(‘head’)[0];
var jus=document.createElement(‘script’);
jus.setAttribute(‘type’,’text/javascript’);
jus.setAttribute(‘src’,’jquery-ui-1.7.1.custom.min.js’);
head.appendChild(jus);
jus.onload = loadms();
jus.onload = console.log(‘jQuery UI Loaded’);
}

function loadms(){
head=document.getElementsByTagName(‘head’)[0];
var ms=document.createElement(‘script’);
ms.setAttribute(‘type’,’text/javascript’);
ms.setAttribute(‘src’,’My Script’);
head.appendChild(ms);
ms.onload = console.log(‘My Script Loaded’);
}
[/CODE]

to post a comment
JavaScript

5 Comments(s)

Copy linkTweet thisAlerts:
@Angry_Black_ManJun 04.2009 — your first problem is that you're overwriting the onload handler.

incorrect logic:

jqs.onload = loadjQueryUI();
jqs.onload = console.log('jQuery Loaded');


your second problem is an extrapolation that i will detail based on code that will follow, and my own observations.

the issue appears to be that when you dont pass an anonymous function to an event handler, the function is IMMEDIATLY fired. that said:

loadjQuery(); [COLOR="Red"]// after all the code is interpreted, this is the first function to fire[/COLOR]

function loadjQuery(){
[COLOR="Red"]// this function begins to run[/COLOR]
head=document.getElementsByTagName('head')[0];
var jqs=document.createElement('script');
jqs.setAttribute('type','text/javascript');
jqs.setAttribute('src','jquery-1.3.2.min.js');
head.appendChild(jqs);
jqs.onload = loadjQueryUI(); [COLOR="Red"]// this function is fired RIGHT NOW[/COLOR]
[COLOR="Red"]// this statement under this comment will run, but ONLY AFTER loadjQueryUI() COMPLETELY FINISHES[/COLOR]
jqs.onload = console.log('jQuery Loaded');
}

function loadjQueryUI(){
[COLOR="Red"]// this function runs when it is told to run[/COLOR]
head=document.getElementsByTagName('head')[0];
var jus=document.createElement('script');
jus.setAttribute('type','text/javascript');
jus.setAttribute('src','jquery-ui-1.7.1.custom.min.js');
head.appendChild(jus);
jus.onload = loadms(); [COLOR="Red"]// oh, hey, now i need to run loadms RIGHT NOW[/COLOR]
[COLOR="Red"]// this next statement will NOT RUN until loadms is finished[/COLOR]
jus.onload = console.log('jQuery UI Loaded');
}

function loadms(){
[COLOR="Red"]// this function begins to run.. right now, the previous two functions are ON HOLD[/COLOR]
head=document.getElementsByTagName('head')[0];
var ms=document.createElement('script');
ms.setAttribute('type','text/javascript');
ms.setAttribute('src','My Script');
head.appendChild(ms);
ms.onload = console.log('My Script Loaded'); [COLOR="Red"]// i do one thing. i print. im done. now the function that called me will finish. and the function that called that function will finish.[/COLOR]
}


in contrast, this code i was testing with uses anonymous functions:

<script>
loadjQuery();

function loadjQuery(){
head=document.getElementsByTagName('head')[0];
var jqs=document.createElement('script');
jqs.setAttribute('type','text/javascript');
jqs.setAttribute('src','test.js');
head.appendChild(jqs);
jqs.onload = function () { loadjQueryUI(); } [COLOR="Red"]// jqs.onload will run loadjqueryui when it loads, as opposed to RIGHT NOW[/COLOR]
jqs.onload = function () { alert('jQuery Loaded'); } [COLOR="Red"]// NOT ANYMORE!! I just overwrote the onload function. THIS WILL BE THE ONLY ALERT SEEN![/COLOR]
}

[COLOR="Red"]// never runs[/COLOR]
function loadjQueryUI(){
head=document.getElementsByTagName('head')[0];
var jus=document.createElement('script');
jus.setAttribute('type','text/javascript');
jus.setAttribute('src','test.js');
head.appendChild(jus);
jus.onload = function () { loadms(); }
jus.onload = function () { alert('jQuery UI Loaded'); }
}

[COLOR="Red"]// never runs[/COLOR]
function loadms(){
head=document.getElementsByTagName('head')[0];
var ms=document.createElement('script');
ms.setAttribute('type','text/javascript');
ms.setAttribute('src','test.js');
head.appendChild(ms);
ms.onload = function () { alert('My Script Loaded'); }
}
</script>


yes, i know. im a f*cking reverse engineering fool!
Copy linkTweet thisAlerts:
@Angry_Black_ManJun 04.2009 — also, to ensure your scripts are written to the head in the correct order, output the result of the "html" object's innerHTML property at various stages in the execution order.

for example:

<script>
alert("the dom before loadjquery is runnn" + document.getElementsByTagName("html")[0].innerHTML)
loadjQuery();

function loadjQuery(){
head=document.getElementsByTagName('head')[0];
var jqs=document.createElement('script');
jqs.setAttribute('type','text/javascript');
jqs.setAttribute('src','test1.js');
head.appendChild(jqs);
jqs.onload = function () { alert('jQuery Loadednn' + document.getElementsByTagName("html")[0].innerHTML); loadjQueryUI(); }
}

function loadjQueryUI(){
head=document.getElementsByTagName('head')[0];
var jus=document.createElement('script');
jus.setAttribute('type','text/javascript');
jus.setAttribute('src','test2.js');
head.appendChild(jus);
jus.onload = function () { alert('jQuery UI Loadednn' + document.getElementsByTagName("html")[0].innerHTML); loadms(); }
}

function loadms(){
head=document.getElementsByTagName('head')[0];
var ms=document.createElement('script');
ms.setAttribute('type','text/javascript');
ms.setAttribute('src','test3.js');
head.appendChild(ms);
ms.onload = function () { alert('My Script Loadednn' + document.getElementsByTagName("html")[0].innerHTML); }
}
</script>
Copy linkTweet thisAlerts:
@Angry_Black_ManJun 04.2009 — a final thought. there are two ways of assigning a function to a method:

  • 1. by assigning the method an anonymous function, as seen in my previous posts


  • or

  • 2. by assigning the pointer of a function to a method. ex:


  • <script>
    loadjQuery();

    function loadjQuery(){
    head=document.getElementsByTagName('head')[0];
    var jqs=document.createElement('script');
    jqs.setAttribute('type','text/javascript');
    jqs.setAttribute('src','test1.js');
    head.appendChild(jqs);
    jqs.onload = loadjQueryUI
    }

    function loadjQueryUI(){
    head=document.getElementsByTagName('head')[0];
    var jus=document.createElement('script');
    jus.setAttribute('type','text/javascript');
    jus.setAttribute('src','test2.js');
    head.appendChild(jus);
    jus.onload = loadms
    }

    function loadms(){
    head=document.getElementsByTagName('head')[0];
    var ms=document.createElement('script');
    ms.setAttribute('type','text/javascript');
    ms.setAttribute('src','test3.js');
    head.appendChild(ms);
    ms.onload = function () { alert('My Script Loaded. if all is right, the HTML printout below will show that the scripts were appended to the head in 1/2/3 order:nn' + document.getElementsByTagName("html")[0].innerHTML); }
    }
    </script>


    notice how the functions assigned to the method do not contain the parenthesis [()]. if the parenthesis are there, this tells the script to actually execute that function. unfortunately, many coders assume this means that youre passing a function pointer to the method. as a matter of fact, the only thing youre passing to the method is whatever the return is of the function is. in this case, it's an "undefined"

    <script>

    test = fun()

    alert(test) // alerts "undefined" because fun has no return

    function fun()
    {
    // even when you dont explicitly do it
    // a function ALWAYS has a return

    // for this reason, am implicit return is executed
    // but there is nothing to return. thus: undefined
    }
    </script>
    Copy linkTweet thisAlerts:
    @rnd_meJun 04.2009 — script.onload is not standard, and won't always work (even though it's great for firefox).

    don't rely on script tag event working.

    it's a lot simple to add a single line to the bottom of two of the scripts:

    in 'jquery-1.3.2.min.js', the last line would be:
    [CODE]loadjQueryUI()[/CODE]

    in 'jquery-ui-1.7.1.custom.min.js', the last line would be:
    [CODE]loadms()[/CODE]

    works in every browser.

    if you can't modify the actual files, a one or two line php script could echo the file,

    with the extra js at the bottom, to load the next script based upon GET params...


    this is simpler and more reliable and scalable than trying to balance load events.

    ----------[COLOR="Red"]

    EDIT:

    [/COLOR]


    i just came up with this one.

    another way to do this without modifying the js files is by using object detection and timeouts:


    [CODE]
    function addScript(u){
    var sc2=document.createElement('script'); sc2.src=u;

    document.getElementsByTagName('*')[1].appendChild(sc2)
    }//end addScript()

    function waitForLoad(url, strCondition) {
    setTimeout(function () {
    if (eval(strCondition)) {
    addScript(url);
    } else {
    setTimeout(arguments.callee, 125)
    }
    }, 150);
    }//end waitForLoad()

    addScript( 'jquery-1.3.2.min.js');
    waitForLoad('jquery-ui-1.7.1.custom.min.js', "window.jQuery");
    waitForLoad('test3.js', "window.jQuery && window.jQuery.ui");

    [/CODE]



    if you can find "smoking gun" globals from each script, you won't need to use eval.

    you would simply pass a string of the global's expected variable name,

    and change the waitForLoad function's checker from:

    [CODE]
    if (eval(strCondition)) {[/CODE]

    to
    [CODE]if (window[strCondition]) {[/CODE]

    this would be more efficient, but it probably wont matter unless you are adding LOTS of scripts.
    Copy linkTweet thisAlerts:
    @racerxfactorJul 20.2009 — I thought about opening my own thread but this thread is the closest I've found to my solution.

    I have about 5 scripts running on a page, I would like to set delays and priorities to when they load. They are in the order of what I want BUT the scripts loading later in the page are loading faster and delaying the first script loading.

    How can I set up priorities and delays for the scripts - some are on the page and other are externally linked.
    ×

    Success!

    Help @salbito spread the word by sharing this article on Twitter...

    Tweet This
    Sign in
    Forgot password?
    Sign in with TwitchSign in with GithubCreate Account
    about: ({
    version: 0.1.9 BETA 5.6,
    whats_new: community page,
    up_next: more Davinci•003 tasks,
    coming_soon: events calendar,
    social: @webDeveloperHQ
    });

    legal: ({
    terms: of use,
    privacy: policy
    });
    changelog: (
    version: 0.1.9,
    notes: added community page

    version: 0.1.8,
    notes: added Davinci•003

    version: 0.1.7,
    notes: upvote answers to bounties

    version: 0.1.6,
    notes: article editor refresh
    )...
    recent_tips: (
    tipper: @AriseFacilitySolutions09,
    tipped: article
    amount: 1000 SATS,

    tipper: @Yussuf4331,
    tipped: article
    amount: 1000 SATS,

    tipper: @darkwebsites540,
    tipped: article
    amount: 10 SATS,
    )...