4

For this userscript I'm writing, I need to use a third-party JavaScript library which has 3 JavaScript files. Since @require doesn't work on Chrome, how can I add multiple external JavaScript libraries to a userscript? I'm considering all the possibilities before choosing one.

I know you can add jQuery using this method. I have personally used that. Is it possible to add other libraries using this work-around as well?

Community
  • 1
  • 1
Isuru
  • 30,617
  • 60
  • 187
  • 303

3 Answers3

4

Try adding following function in your userscript,

/**
 * Dynamically loading javascript files.
 *
 * @param filename url of the file
 * @param callback callback function, called when file is downloaded and ready
 */
function loadjscssfile(filename, callback) {
    var fileref = document.createElement('script')
    fileref.setAttribute("type", "text/javascript")
    fileref.setAttribute("src", filename)
    if (fileref.readyState) {
        fileref.onreadystatechange = function() { /*IE*/
            if (fileref.readyState == "loaded" || fileref.readyState == "complete") {
                fileref.onreadystatechange = null;
                callback();
            }
        }
    } else {
        fileref.onload = function() {  /*Other browsers*/
            callback();
        }
    }

    // Try to find the head, otherwise default to the documentElement
    if (typeof fileref != "undefined")
        (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(fileref)
}

As the files are loaded asynchronously, and order of the loading of files is not guaranteed, than for multiple external files, call this function in a chined function e.g.

loadjscssfile("http://code.jquery.com/jquery-1.6.3.min.js", function() {
    loadjscssfile("http://www.abc.org./script/otherFile.js", function() {
       // call your function that depends on the external libriries here.
     });
});

Chain as many exeternal files as you need, the order of loading files will be properly preserved. Hope this helps, all best

Master Slave
  • 27,771
  • 4
  • 57
  • 55
  • Thank you so very much for posting a solution! I really appreciate it. :) I modified your code according to my situation. Since its a bit lengthy, I posted it [here](http://paste2.org/p/1851096). Can you please just go through the code and let me know if I have done something wrong? and can you please explain this single line of code. Since I'm new to JS, I don't quite get everything.. `if (typeof fileref != "undefined")` Thank a lot again.. – Isuru Jan 03 '12 at 19:12
  • 1
    Hi, I glanced through your code. I actually pasted the code with one extra parenthesis. Line `if (typeof fileref != "undefined") (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(fileref)` belongs to loadjscssfile function. And actually, I modified the original function and pasted the part that only downloads javascript. Originally, the function was also downloading external CSS, and that is where typeof filref came from, it checks whether javascript object exists. You don't need this check, as fileref will always be a script element object, best – Master Slave Jan 04 '12 at 13:23
  • One quick question. It sounds dumb but anyway, after injecting those .js files into the `head` of the page, can I see them there if I view the page source?? 'Cause I executed the script with just injection part to see if it works but I don't see them.. – Isuru Jan 05 '12 at 18:11
  • You won't see the files by browsing the source code. But you have some very good tools, that can help you with this. As you say that you are new to JavaScript development, Firebug extension for Firefox or Java Console for Chrome (just press F12) will help you a great deal. – Master Slave Jan 06 '12 at 13:00
  • I checked out the code using those tools but it seems only the first .js file is getting injected. btw I got another similar solution and it seems to work. I've posted it as an answer :) – Isuru Jan 07 '12 at 10:33
1

While the other answers will work as well, I'd needed a little more flexibility. Here's the version I'd come up with: http://userscripts.org/scripts/show/123588

BrianFreud
  • 7,094
  • 6
  • 33
  • 50
0
function requireFiles(jsLibs, callback) 
{
    //array to hold the external libabry paths
    var jsLibs = new Array();
    jsLibs[0] = "http://code.jquery.com/jquery-1.7.1.min.js"
    jsLibs[1] = "https://raw.github.com/gildas-lormeau/zip.js/master/WebContent/zip.js"
    jsLibs[2] = "https://raw.github.com/gildas-lormeau/zip.js/master/WebContent/deflate.js"
    jsLibs[3] = "https://raw.github.com/gildas-lormeau/zip.js/master/WebContent/inflate.js"

    var index = 0;
    var requireNext = function() 
    {
        var script = document.createElement("script");
        if (index < jsLibs.length) 
        {
            script.addEventListener("load", requireNext, false);
            script.setAttribute("src", jsLibs[index++]);
        }
        else 
        {
            script.textContent = "(" + callback.toString() + ")()";
        }
        document.body.appendChild(script);
    }
    requireNext();
}


function otherCode()
{
    //rest of the script
}

requireFiles(otherCode);
Isuru
  • 30,617
  • 60
  • 187
  • 303