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
  • what about onerror tag? stackoverflow.com/q/538745/1211174 Commented Apr 23, 2014 at 18:31
  • There is onerror event for the script tag. It will fire when the resource not found. Commented Jun 18, 2021 at 10:12

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();
Sign up to request clarification or add additional context in comments.

5 Comments

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: 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.
Why do you use !== 'undefined' instead of (what I thought was the norm) != 'undefined'?
!= 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.
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)... "
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 Comment

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.
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.

Comments

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);    

Comments

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.

Comments

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 Comment

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
0

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

Comments

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.

Comments

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);

Comments

-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()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.