8

We have some software which re-creates javascript files. We need to be able to re-load them into the DOM without refreshing the page. This means that the original javascript file (already loaded by the browser) has changed. Usually a refresh of the browser gets around this, but we can't do that due to losing state in other controls.

My searches for this have only returned results about refreshing the browser with javascript, which is not what I want.

Is it possible to reload the javascript file without refreshing the browse with only JavaScript (no JQuery/Angular or any third party library/framework etc)?

MyDaftQuestions
  • 4,487
  • 17
  • 63
  • 120
  • I'm happy to use Ajax @Netzach if you know how to do it – MyDaftQuestions Oct 05 '16 at 17:28
  • in essence, this involves searching the dom tree for the existing script and replacing it. however, don't expect this to "reset" the browser's memory; variables and methods from the original script are still going to be accessible. see http://www.javascriptkit.com/javatutors/loadjavascriptcss2.shtml for a general idea on the process. – Claies Oct 05 '16 at 17:31
  • possible duplicate: http://stackoverflow.com/questions/21294/dynamically-load-a-javascript-file – muratgu Oct 05 '16 at 17:31
  • It is not entirely clear what you are trying to do here. What do you mean 'software which recreates javascript files'? Does this happen on the client or server? Does it happen dynamically in response to subsequent client requests? – Jared Smith Oct 05 '16 at 17:32
  • Good comment @JaredSmith, I updated my answer which I hope answers you. Basically, client loads javascript. Makes changes which does some changes on the server . The server then overwrites the existing javascript file. – MyDaftQuestions Oct 05 '16 at 17:36
  • for example you have js1.js script and need to load js2.js script var imported = document.createElement('script'); imported.src = 'js2.js'; document.head.appendChild(imported); – Netzach Oct 05 '16 at 17:39
  • @MyDaftQuestions in that case svidgen's answer is the best: you cannot reliably do this in non-trivial cases unless you are doing something fairly extreme (i.e. switching to clojurescript and using figwheel). See his answer for details about why. But oh, would life be *soooo* much easier if you could. – Jared Smith Oct 05 '16 at 17:55

4 Answers4

7

If your intention is to provide data or new widgets:

Vanilla AJAX is simple and ubiquitous. Do that.

If you're averse to that, for whatever reason, and if you're pulling new data exclusively from boxes you control, you could also give JSONP a try.

var s = document.createElement('script');
s.src = 'path/to/script-that-injects-data-or-NEW-widgets.js';
document.body.appendChild(s);

If your intention is to "upgrade" the page or replace functionality:

Just don't do this. While you can easily add new scripts, you can't reliably "cleanse" the page of old scripts or variables without a lot of bookkeeping. Unless your scripts are very very very simple, you can expect no small amount of trouble.

A better solution would be to notify the user of upgrades, ask them to refresh the page, and make sure your app can quickly reinitialize to it's previous state.

Ultimately, if you want to "upgrade" the application in-place, you'll want to refresh everything behind the scenes anyway. And that means you need to know how to rebuild everything to match the existing/prior state anyway. And, you could do this. But, it'll be easier to just refresh the page, which better ensures a clean, compatible state without a lot of fuss.

svidgen
  • 13,744
  • 4
  • 33
  • 58
  • The point about upgrading the code to replace functionality IS what the program does. Sadly. It's out of my control it's been coded poorly by the C guys, who are some what old fashioned (it's a single file 20k lines long of javascript... no testability etc). :( Regardless, I agree with the point, as such I feel that although it's not the actual solution I need, it's still the right answer. – MyDaftQuestions Oct 07 '16 at 16:54
4

It is possible.

Have a look at lite-server:

Lightweight development only node server that serves a web app, opens it in the browser, refreshes when html or javascript change, injects CSS changes using sockets, and has a fallback page when a route is not found.

It uses BrowserSync internally, which:

... injects a small script into every page which communicates with the server via WebSockets. When an event occurs — such as a file modification or scroll action — the server sends an update notification to all connected devices.

If you cannot use 3rd-party code you can reimplement something like that yourself.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271
0
function loadScript(src, callback)
{
  var script,
      scriptTag;
  script = document.createElement('script');
  script.type = 'text/javascript';
  script.src = src;
  script.onload = script.onreadystatechange = function() {
    if (!this.readyState || this.readyState == 'complete' )
    {
      callback();
    }
  };
  scriptTag = document.getElementsByTagName('script')[0];
  scriptTag.parentNode.insertBefore(script, sriptTag);
}
StackOverMySoul
  • 1,957
  • 1
  • 13
  • 21
  • does this mean as soon as we add this tag to the dom, the browser can use it? I honeslty thought the browser would only know the external references on load... Is my understanding wrong? – MyDaftQuestions Oct 05 '16 at 17:31
  • @MyDaftQuestions: Yes. When you add a ` – Felix Kling Oct 05 '16 at 17:32
-1

Add another < script src="xxx"/ > tag to the bottom of your page. It should load the js and 'override' the objects defined in your previous script.

TheSavage
  • 269
  • 1
  • 10