30

So if I have the following:

<script type="text/javascript" src="offsite file I am referencing"></script>

and I simply want to delay the execution of calling that file using settimeout, how would I go about that?

Very strange in that I would have no problem using settimeout on a simple function, but I am kind of stumped in this seemingly more simple situation.

My thought would be I could just make a function that calls that file after x amount of time, but calling the file in the function seems to be escaping me.

Dennis
  • 32,200
  • 11
  • 64
  • 79
absentx
  • 1,397
  • 4
  • 17
  • 31

8 Answers8

47

you are almost there.

in your settimeout callback function do the following:

var script = document.createElement('script');
script.src = "http://whatever.com/the/script.js";
document.getElementsByTagName('head')[0].appendChild(script);
Vijay Agrawal
  • 3,751
  • 2
  • 23
  • 25
  • 1
    Thanks, I basically had this figured out and I couldn't make it back here fast enough to update!! – absentx Mar 08 '12 at 01:33
  • I stumbled onto this anwser before finding the answer I really wanted using jQuery and promises here: [link](http://stackoverflow.com/questions/11803215/how-to-include-multiple-js-files-using-jquery-getscript-method) – Simon Hutchison Aug 18 '16 at 01:51
17

The simplest way would be to let the script file load normally and just call a main function in it with setTimeout() like this:

<script type="text/javascript" src="offsite file I am referencing"></script>
<script type="text/javascript">
setTimeout(executeMainFunction, 5000);    // function in offsite js file
</script>

If you cannot do that for some reason, then you can delay the loading of the external script file like this:

setTimeout(function() {
    var headID = document.getElementsByTagName("head")[0];         
    var newScript = document.createElement('script');
    newScript.type = 'text/javascript';
    newScript.src = 'http://www.somedomain.com/somescript.js';
    headID.appendChild(newScript);
}, 5000);

Here's a reference article on dynamic loading of script files (and other types of resources): http://www.hunlock.com/blogs/Howto_Dynamically_Insert_Javascript_And_CSS.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
6

You can use DOM manipulation to create a new script tag at runtime. Adding it into the document will load the external JS file just as if you had written it into the HTML in the first place.

var loadScript = function(sourceSrc){
    var scriptTag = document.createElement('script');
    scriptTag.src = scriptSrc;
    document.getElementsByTagName('head')[0].appendChild(scriptTag);
}
hugomg
  • 68,213
  • 24
  • 160
  • 246
4

You can delay the script from loading, until the page finishes loading, using the HTML script defer attribute:

<script src="offsite file I am referencing" defer></script>
derloopkat
  • 6,232
  • 16
  • 38
  • 45
3

If the purpose of this exercise is to delay the loading of external resources to simulate potential real life scenarios (e.g. when loading 3rd party widgets, etc), then I'd go down a very different route.

The following are two different delay proxy implementations that can be used to simulate and test unexpected network conditions:

They both work by using a prefix like /delay/5000/ to specify the delay simulation period.

Hady
  • 2,597
  • 2
  • 29
  • 34
2

Mozilla Developer Network explains various approaches:

MDN Async Script Techniques

<script async src="file.js"></script>

or

var script = document.createElement('script');
script.src = "file.js";
document.body.appendChild(script);

or if your JavaScript is in a String:

var blob = new Blob([codeString]);
var script = document.createElement('script');
var url = URL.createObjectURL(blob);
script.onload = script.onerror = function() { URL.revokeObjectURL(url); };
script.src = url;
document.body.appendChild(script);

There is also good information when async is not async as well as how to get around those cases.

Community
  • 1
  • 1
0

I have created for ReactJS and its worked for me.

1. File: widget.js with promise:

const delayTime = 20000; // loading 20sec delay.

const loadJS = async () => {
    return await new Promise(function (resolve, reject) {
        var script = document.createElement('script');
        script.type = 'text/javascript';
        script.async = true;
        script.src = 'https://yoururl.com/js/widget.js';
        script.onload = resolve;
        script.onerror = () => {
            reject('Cannot load js')
            document.head.removeChild(script);
        }
        document.head.appendChild(script);
    }) }

function initLoadJS() {
    loadJS()
    .then(()=> console.log('testing'))
    .catch((error)=>console.error(error)) }

function delayLoadingJS() {
    setTimeout((event)=>initLoadJS(event), delayTime); 
} 
export default delayLoadingJS;

2. Calling delayLoadingJS() function on the page:

When page loading completed then after 20 sec later initLoadJS() method will trigger and it attach the 3rd party javascript file(https://yoururl.com/js/widget.js) on page.

componentDidUpdate(prevProps, prevState) {
    if (this.state.page !== prevState.page) {

      delayLoadingJS();
    }
}
Santosh Singh
  • 1,112
  • 14
  • 14
0

For a NextJS cript, the code below will work fine:

<script  id="sample_id">
    setTimeout(function(){
        var script = document.createElement('script');
        script.src = "https://link_to_load";
        document.getElementsByTagName('head')[0].appendChild(script);
     },
     4000);
</script>
ahuemmer
  • 1,653
  • 9
  • 22
  • 29
Rajaraman
  • 21
  • 4