Verify External Script Is Loaded

@jasper's answer is totally correct but with modern browsers, a standard Javascript solution could be:

function isScriptLoaded(src)
{
    return Boolean(document.querySelector('script[src="' + src + '"]'));
}

UPDATE July 2021:

The accepted solutions above have changed & improved much over time. The scope of my previous answer above was only to detect if the script was inserted in the document to load (and not whether the script has actually finished loading).

To detect if the script has already loaded, I use the following method (in general):

  1. Create a common library function to dynamically load all scripts.
  2. Before loading, it uses the isScriptLoaded(src) function above to check whether the script has already been added (say, by another module).
  3. I use something like the following loadScript() function to load the script that uses callback functions to inform the calling modules if the script finished loading successfully.
  4. I also use additional logic to retry when script loading fails (in case of temporary network issues).
    1. Retry is done by removing the <script> tag from the body and adding it again.
    2. If it still fails to load after configured number of retries, the <script> tag is removed from the body.
    3. I have removed that logic from the following code for simplicity. It should be easy to add.

/** 
 * Mark/store the script as fully loaded in a global variable.
 * @param src URL of the script
 */
function markScriptFullyLoaded(src) {
    window.scriptLoadMap[src] = true;
}

/** 
 * Returns true if the script has been added to the page
 * @param src URL of the script
 */
function isScriptAdded(src) {
    return Boolean(document.querySelector('script[src="' + src + '"]'));
}

/** 
 * Returns true if the script has been fully loaded
 * @param src URL of the script
 */
function isScriptFullyLoaded(src) {
    return src in window.scriptLoadMap && window.scriptLoadMap[src];
}

/** 
 * Load a script. 
 * @param src URL of the script
 * @param onLoadCallback Callback function when the script is fully loaded
 * @param onLoadErrorCallback Callback function when the script fails to load
 * @param retryCount How many times retry laoding the script? (Not implimented here. Logic goes into js.onerror function)
 */
function loadScript(src, onLoadCallback, onLoadErrorCallback, retryCount) {
    if (!src) return;
    
    // Check if the script is already loaded
    if ( isScriptAdded(src) )
    {
        // If script already loaded successfully, trigger the callback function
        if (isScriptFullyLoaded(src)) onLoadCallback();
        
        console.warn("Script already loaded. Skipping: ", src);
        return;
    }

    // Loading the script...
    const js = document.createElement('script');
    js.setAttribute("async", "");
    js.src = src;
    
    js.onload = () => {
        markScriptFullyLoaded(src)
        
        // Optional callback on script load
        if (onLoadCallback) onLoadCallback();
    };
    
    js.onerror = () => {
        // Remove the script node (to be able to try again later)
        const js2 = document.querySelector('script[src="' + src +'"]');
        js2.parentNode.removeChild(js2);
        
        // Optional callback on script load failure
        if (onLoadErrorCallback) onLoadErrorCallback();
    };

    document.head.appendChild(js);
}


If the script creates any variables or functions in the global space you can check for their existance:

External JS (in global scope) --

var myCustomFlag = true;

And to check if this has run:

if (typeof window.myCustomFlag == 'undefined') {
    //the flag was not found, so the code has not run
    $.getScript('<external JS>');
}

Update

You can check for the existence of the <script> tag in question by selecting all of the <script> elements and checking their src attributes:

//get the number of `<script>` elements that have the correct `src` attribute
var len = $('script').filter(function () {
    return ($(this).attr('src') == '<external JS>');
}).length;

//if there are no scripts that match, the load it
if (len === 0) {
    $.getScript('<external JS>');
}

Or you can just bake this .filter() functionality right into the selector:

var len = $('script[src="<external JS>"]').length;

Few too many answers on this one, but I feel it's worth adding this solution. It combines a few different answers.

Key points for me were

  • add an #id tag, so it's easy to find, and not duplicate
  • Use .onload() to wait until the script has finished loading before using it

    mounted() {
      // First check if the script already exists on the dom
      // by searching for an id
      let id = 'googleMaps'
      if(document.getElementById(id) === null) {
        let script = document.createElement('script')
        script.setAttribute('src', 'https://maps.googleapis.com/maps/api/js?key=' + apiKey)
        script.setAttribute('id', id)
        document.body.appendChild(script) 
    
        // now wait for it to load...
        script.onload = () => {
            // script has loaded, you can now use it safely
            alert('thank me later')
            // ... do something with the newly loaded script
        }      
      }
    }