How to force a script reload and re-execute?

226,825

Solution 1

How about adding a new script tag to <head> with the script to (re)load? Something like below:

<script>
   function load_js()
   {
      var head= document.getElementsByTagName('head')[0];
      var script= document.createElement('script');
      script.src= 'source_file.js';
      head.appendChild(script);
   }
   load_js();
</script>

The main point is inserting a new script tag -- you can remove the old one without consequence. You may need to add a timestamp to the query string if you have caching issues.

Solution 2

Here's a method which is similar to Kelly's but will remove any pre-existing script with the same source, and uses jQuery.

<script>
    function reload_js(src) {
        $('script[src="' + src + '"]').remove();
        $('<script>').attr('src', src).appendTo('head');
    }
    reload_js('source_file.js');
</script>

Note that the 'type' attribute is no longer needed for scripts as of HTML5. (http://www.w3.org/html/wg/drafts/html/master/scripting-1.html#the-script-element)

Solution 3

Creating a new script tag and copying the contents of the existing script tag, and then adding it, works well.

var scriptTag = document.createElement('script');
scriptTag.innerText = "document.body.innerHTML += 'Here again ---<BR>';";
var head = document.getElementsByTagName('head')[0];
head.appendChild(scriptTag);

setInterval(function() {
    head.removeChild(scriptTag);
    var newScriptTag = document.createElement('script');
    newScriptTag.innerText = scriptTag.innerText;
    head.appendChild(newScriptTag);
    scriptTag = newScriptTag;    
}, 1000);

This won't work if you expect the script to change every time, which I believe is your case. You should follow Kelly's suggestion, just remove the old script tag (just to keep the DOM slim, it won't affect the outcome) and reinsert a new script tag with the same src, plus a cachebuster.

Solution 4

Small tweak to Luke's answer,

 function reloadJs(src) {
    src = $('script[src$="' + src + '"]').attr("src");
    $('script[src$="' + src + '"]').remove();
    $('<script/>').attr('src', src).appendTo('head');
}

and call it like,

reloadJs("myFile.js");

This will not have any path related issues.

Solution 5

Use this function to find all script elements containing some word and refresh them.

function forceReloadJS(srcUrlContains) {
  $.each($('script:empty[src*="' + srcUrlContains + '"]'), function(index, el) {
    var oldSrc = $(el).attr('src');
    var t = +new Date();
    var newSrc = oldSrc + '?' + t;

    console.log(oldSrc, ' to ', newSrc);

    $(el).remove();
    $('<script/>').attr('src', newSrc).appendTo('head');
  });
}

forceReloadJS('/libs/');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

Share:
226,825
Jonathan M
Author by

Jonathan M

Live and let dev. :)

Updated on December 09, 2020

Comments

  • Jonathan M
    Jonathan M over 3 years

    I have a page that is loading a script from a third party (news feed). The src url for the script is assigned dynamically on load up (per third party code).

    <div id="div1287">
        <!-- dynamically-generated elements will go here. -->
    </div>
    
    <script id="script0348710783" type="javascript/text">
    </script>
    
    <script type="javascript/text">
        document.getElementById('script0348710783').src='http://oneBigHairyURL';
    </script>
    

    The script loaded from http://oneBigHairyURL then creates and loads elements with the various stuff from the news feed, with pretty formatting, etc. into div1287 (the Id "div1287" is passed in http://oneBigHairyURL so the script knows where to load the content).

    The only problem is, it only loads it once. I'd like it to reload (and thus display new content) every n seconds.

    So, I thought I'd try this:

    <div id="div1287">
        <!-- dynamically-generated elements will go here. -->
    </div>
    
    <script id="script0348710783" type="javascript/text">
    </script>
    
    <script type="javascript/text">
        loadItUp=function() {
            alert('loading...');
            var divElement = document.getElementById('div1287');
            var scrElement = document.getElementById('script0348710783');
    
            divElement.innerHTML='';
            scrElement.innerHTML='';
            scrElement.src='';
            scrElement.src='http://oneBigHairyURL';
            setTimeout(loadItUp, 10000);
        };
        loadItUp();
    </script>
    

    I get the alert, the div clears, but no dynamically-generated HTML is reloaded to it.

    Any idea what I'm doing wrong?

  • Ruan Mendes
    Ruan Mendes about 12 years
    For cache problems, the best thing is to add a timestamp to the url 'hello.js?cachebuster='+ new Date().getTime()
  • Md. Salahuddin
    Md. Salahuddin over 9 years
    Great!! It helps me a lot after a lot of searching. Thanks.
  • Jonathan M
    Jonathan M about 8 years
    Shouldn't it .appendTo('head') instead of the body?
  • Maleen Abewardana
    Maleen Abewardana about 8 years
    @JonathanM We normally keep our script at the end of the body. When I was posting this, this worked for me. I think you can also append to head, if needed.
  • user984003
    user984003 over 7 years
    You can add new JS, but you can't get rid of the old. Any listeners, etc. from the original script will still be live even if you remove its script tag.
  • Admin
    Admin almost 5 years
    This is the one
  • Admin
    Admin almost 5 years
    @Juan Mendes, thats correct because a news feed has to be loaded again. Skip it only when cache is wanted in case only rerun is needed and a new unnessecary load would be a slow down, for example a script that doesnt change.