How to Force a Script Reload and Re-Execute?

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='
</script>

The script loaded from 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 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='
        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?

4

9 Answers

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.

3

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

2

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.

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.

3

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=""></script>
<script src=""></script>

Using PipesJS I can dilute this to

 <dyn insert="here" id="clickity" ajax="url">Click for refresh</dyn>
 <!-- <dyn> is a dynamic linker in PipesJS -->
 <article id="here"></article>

You would use this state to affect the article in the same as the source for the JS.

So using

 <dyn attribution="src-attr" class-attr="src:newjs.js;" id="clickity">Click for refresh</dyn>
 <!-- attribution is the class of tags getting the new attr, src="newjs.js"-->
 <script class="src-attr" src="scripty.js"></script>

will do the same thing as <article> in this scope. It will fill the innerHTML.

if you want to, use an id on the <head> tag.

You can insert preemptive functions and use them in tandem with PipesJS. you can also use functions that come after the call.

If you would rather use a timer this would be performed by creating a

setInterval(function(input) { document.getElementById("clickity").click(); }, 3000);

setInterval() object. 3000 is in ms.

You can see PipesJS here.

I thing just call the function for the new elements after it appended to DOM instead reload all scripts.

1

add a class to your script tag and then wrap your script in a function and add the wrapper function name as an atribute

then do this

const reloadStaticBlocks = () => {
    [...document.querySelectorAll('.script')].map(script => {
        let scriptInnerHtml = script.innerText;
        let scriptAttribute = script.getAttribute('data-function-name')
        let parent = script.parentNode;
        parent.removeChild(script);
        
        var newScriptTag = document.createElement('script');
        newScriptTag.innerText = scriptInnerHtml;
        newScriptTag.className = "static-block-script";
        newScriptTag.setAttribute('data-function-name', scriptAttribute);
        parent.appendChild(newScriptTag);
        return newScriptTag;
    }).map(script => {
        eval(script.getAttribute('data-function-name'))()
    })
};

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

  });
1

Your Answer

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

Chloe Bennett

Chloe Bennett

Culture, Media & Entertainment Columnist

Chloe Bennett explores the intersection of pop culture, streaming entertainment, digital trends, and contemporary lifestyle. Her weekly commentary reaches thousands of culture enthusiasts.

Share this article
Twitter Facebook Pinterest