Bookmarklet wait until Javascript is loaded

cgp picture cgp · Apr 16, 2009 · Viewed 7.1k times · Source

I've got a bookmarklet which loads jQuery and some other js libraries.

How do I:

  • Wait until the javascript library I'm using is available/loaded. If I try to use the script before it has finished loading, like using the $ function with jQuery before it's loaded, an undefined exception is thrown.
  • Insure that the bookmarklet I load won't be cached (without using a server header, or obviously, being that this is a javascript file: a metatag)

Is anyone aware if onload for dynamically added javascript works in IE? (to contradict this post)

What's the simplest solution, cleanest resolution to these issues?

Answer

Vincent Robert picture Vincent Robert · Apr 16, 2009

It depends on how you are actually loading jQuery. If you are appending a script element to the page, you can use the same technique that jQuery uses to dynamically load a script.

EDIT: I did my homework and actually extracted a loadScript function from the jQuery code to use in your bookmarklet. It might actually be useful to many (including me).

function loadScript(url, callback)
{
    var head = document.getElementsByTagName("head")[0];
    var script = document.createElement("script");
    script.src = url;

    // Attach handlers for all browsers
    var done = false;
    script.onload = script.onreadystatechange = function()
    {
        if( !done && ( !this.readyState 
                    || this.readyState == "loaded" 
                    || this.readyState == "complete") )
        {
            done = true;

            // Continue your code
            callback();

            // Handle memory leak in IE
            script.onload = script.onreadystatechange = null;
            head.removeChild( script );
        }
    };

    head.appendChild(script);
}


// Usage: 
// This code loads jQuery and executes some code when jQuery is loaded
loadScript("https://code.jquery.com/jquery-latest.js", function()
{
    $('my_element').hide();
});