100

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?

Jonathan M
  • 16,775
  • 9
  • 55
  • 91
  • 1
    I don't know if the browser understands that you want it to download the js again, since you're trying to load the same url over and over. it probably sees it as the same and doesn't bother. try a caching technique when you change the src: `scrElement.src='http://oneBigHairyURL?v=2'; //auto-increment this value` – Matt K Mar 09 '12 at 23:22
  • @Matt K. Yes, I should have posted that I've tried this, but to no avail. Sorry it wasn't part of the original post. – Jonathan M Mar 12 '12 at 19:51
  • @JonathanM I'm stuck at the same thing, did you find a solution? Adding version doesn't work. – Parth Oct 02 '15 at 06:38
  • 1
    @Dr..Net, the selected answer worked for me. – Jonathan M Oct 02 '15 at 14:28
  • @JonathanM that by generating new script tag, it does work. How about loading the same tag but just changing the value of 'src' attribute? – Parth Oct 02 '15 at 15:05
  • @Dr..Net, the selected answer was the only thing I got to work. Tried changing `src` to no avail. To trim down the DOM, I remove old ` – Jonathan M Oct 02 '15 at 16:44
  • @JonathanM Allright, thanks. – Parth Oct 03 '15 at 10:08
  • I´ve also a reload/refresh problem, may you can help me by fix it? https://stackoverflow.com/a/48916962/9392215 – Daniel Stappenbeck Feb 21 '18 at 23:23

6 Answers6

91

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.

Chuck Le Butt
  • 45,923
  • 58
  • 187
  • 280
Kelly
  • 36,733
  • 4
  • 39
  • 51
  • 27
    For cache problems, the best thing is to add a timestamp to the url `'hello.js?cachebuster='+ new Date().getTime() ` – Juan Mendes Mar 09 '12 at 23:36
  • @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. –  Aug 04 '19 at 21:54
44

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)

Luke
  • 16,799
  • 14
  • 90
  • 108
12

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.

Juan Mendes
  • 85,853
  • 29
  • 146
  • 204
7

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.

fugu
  • 6,127
  • 4
  • 34
  • 73
Maleen Abewardana
  • 12,244
  • 3
  • 37
  • 38
6

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>
stomy
  • 1,479
  • 1
  • 14
  • 15
-2

I know that is to late, but I want to share my answer. What I did it's save de script's tags in a HTML file, locking up the scripts on my Index file in a div with an id, something like this.

<div id="ScriptsReload"><script src="js/script.js"></script></div>

and when I wanted to refresh I just used.

$("#ScriptsReload").load("html_with_scripts_tags.html", "", function(
    response,
    status,
    request
  ) {

  });