How to force a script reload and re-execute?
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>
Comments
-
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. intodiv1287
(the Id "div1287" is passed inhttp://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 about 12 yearsFor cache problems, the best thing is to add a timestamp to the url
'hello.js?cachebuster='+ new Date().getTime()
-
Md. Salahuddin over 9 yearsGreat!! It helps me a lot after a lot of searching. Thanks.
-
Jonathan M about 8 yearsShouldn't it
.appendTo('head')
instead of the body? -
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 over 7 yearsYou 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 almost 5 yearsThis is the one
-
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.