17

I am using the following technique to load up Javascript dynamically:

var script = document.createElement("script");
script.type = "text/javascript";
script.src = "file.js";
document.body.appendChild(script);

It's quite a common approach. It's also discussed here: http://www.nczonline.net/blog/2009/06/23/loading-javascript-without-blocking/

I know how to get notified once the file has been loaded and executed

What I don't know is that if the link to the Javascript source file is broken how can I be notified.

Thanks

2

10 Answers 10

26

Listening for events on script elements is not considered reliable (Source). One option that comes to mind is to use setTimeout() to poll for a variable that you expect to be defined in your external script. After x seconds, you could timeout your poll and consider the script as broken.

External Script: file.js:

var MyLibrary = { };

Main document:

var poll;
var timeout = 100; // 10 seconds timeout
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = 'file.js';
document.body.appendChild(script);

poll = function () {
  setTimeout(function () {
    timeout--;
    if (typeof MyLibrary !== 'undefined') {
      // External file loaded
    }
    else if (timeout > 0) {
      poll();
    }
    else {
      // External library failed to load
    }
  }, 100);
};

poll();
5
  • I wish though there was a better one. I could think decide to timeout just a millisecond before the answer comes back if I deal with a slow server.
    – Lx1
    Commented Sep 22, 2010 at 13:02
  • @Lx1: Yes, you could reduce the timeout of setTimeout to 10 or 20 milliseconds actually. If I remember correctly 10 is the minimum timeout for most browsers. Commented Sep 22, 2010 at 16:34
  • Why do you use !== 'undefined' instead of (what I thought was the norm) != 'undefined'?
    – ashes999
    Commented Mar 23, 2014 at 2:25
  • != is comparing values, !== is comparing references. If you use === to compare values, it will also work as expected. If you use == to compare references containing the same value, you are comparing by value, and reference otherwise. Commented Oct 29, 2014 at 11:16
  • The source poo-pooing event listening script load events is outdated (2007).. contains this gem "This works fine on every modern_browser I've tested (IE 5.0 and 7.0; Firefox 2.0; Safari 1.3; Opera 7.54 and 9.10; Konqueror 3.5; iCab 3.0)... "
    – Brad Kent
    Commented Nov 7, 2016 at 15:30
3

It's pretty easy, Internet Explorer will trigger an onreadystatechange event while others will trigger a onload event for the script object.

var newScript;
var loadFunc = function ()
{
    alert("External Javascript File has been loaded");
};
newScript = document.createElement('script');
newScript.setAttribute('type','text/javascript');
newScript.setAttribute('src','file.js');

//IE triggers this event when the file is loaded
if (elm.attachEvent)
{
    newScript.attachEvent('onreadystatechange',function() 
    {
        if (newScript.readyState == 'complete' || newScript.readyState == 'loaded')
            loadFunc();
    });
}

//Other browsers trigger this one
if (newScript.addEventListener)
    newScript.addEventListener('load', loadFunc, false);

document.getElementsByTagName('head')[0].appendChild(newScript);
1
  • 4
    It's not pretty easy. They will trigger that update if the script was loaded. I am asking how to detect if the script was not there.
    – Lx1
    Commented Sep 22, 2010 at 12:48
3
var script = document.createElement("script");
script.type = "text/javascript";
script.src = "file.js";

You need to add a callback for this script.

1st: Create the call back:

function callbackFn(callbackArgs) = {
       console.log("script is loaded with the arguments below");
       console.log(callbackArgs);
    }

2nd: Add an event listener to the script. Both Firefox and Chrome support onload event so you can use it like this:

script.onload = callbackFn();

For IE... You can add an event listener for a state change like this:

script.onreadystatechange = function() {
    if ( this.readyState != "loaded" ) return;
    callbackFn();
    }

Last: Append the script to the body like you used to do.

document.body.appendChild(script);

For further information, please refer to this acticle.

3

Loading a script dynamically is much more simple:

var script = document.createElement('script');
script.onload = function () {
  main_function();  // Main function to call or anything else or nothing  
};
script.src = "yourscript.js";
document.head.appendChild(script);    
1

You can append an onload attribute and in that attribute, you can call a function which will be executed after the JS file has loaded.

Check the code:

var jsElement = document.createElement("script");
jsElement.type = "application/javascript";
jsElement.src = "http://code.jquery.com/jquery-latest.min.js";
jsElement.setAttribute("onload","getMeAll()");
document.body.appendChild(jsElement);
function getMeAll(){
    //your code goes here
}

Hope this helps.

0

One way would be to define a variable in the script you include and then check whether this variable is defined, or not.

1
  • The problem is... When do you check for the variable? The <script> loads asynchronously, and attaching events to <script> elements is not reliable: unixpapa.com/js/dyna.html Commented Sep 22, 2010 at 11:44
0

In the onload event, there are status codes. 200 is good, 404 as you may recall means a file is not found. Helpful?

0

Recently in my vue.js project I tried to something like this, I am using es6 so make sure you have the setup. This is just vanilla javascript, so this should run without any issue.

function handleLoad() {
  // on scirpt loaded logic goes here
  ...
};

function handleLoadError(yourScript) {
  // on scirpt loading error logic goes here
  ...

  // remove the script element from DOM if it has some error
  document.head.removeChild(yourScript);
};

function generatePan(token) {
  // if script does not exist only then append script to DOM
  if (!document.getElementById('your-script')) {
    const yourScript = document.createElement('script');
    yourScript.setAttribute('src', 'https://your-script.js');
    yourScript.setAttribute('id', 'your-script');
    yourScript.async = true;
    yourScript.addEventListener('load', () => handleLoad(), false);
    yourScript.addEventListener('error', () => handleLoadError(yourScript), false);

    document.head.appendChild(yourScript);
  } else {
    // runs if script is already loaded DOM
    handleLoad();
  }
};

Also, please check this link, even this may help.

0

Sorry for the necroposting, but this was my first hit for this exact situation and I believe I have found a better answer: (at least) now you can do the onload event callback from any HTML element to execute code after loaded into the DOM, and you can use it like this:

const script = document.createElement("script");
script.type = "text/javascript";
script.src = "file.js";
script.onload(() => {
    // ...whatever you want to excecute after loadinng the script
})
document.body.appendChild(script);
-2

What JavaScript library do you use?

In jQuery if you load the script via Ajax, you have an option to run a success callback function (and other types of callbacks)...

There is also a dedicated function for loading scripts: $.getScript()

0

Not the answer you're looking for? Browse other questions tagged or ask your own question.