33

I am including pages using Ajax but I also need to include their respective javascript files, which requires removing the previous javascript files from memory at the same time.

How can I unload the currently-loaded javascript files (as well as their code in memory) so that I can load the new page's files? They will more than likely conflict, so having multiple independent files' javascript files loaded.

Jackie
  • 1,630
  • 2
  • 15
  • 12

6 Answers6

12

This really sounds like you need to reevaluate your design. Either you need to drop ajax, or you need to not have collisions in you method names.

You can review this link: http://www.javascriptkit.com/javatutors/loadjavascriptcss2.shtml

Which gives information on how to remove the javascript from the DOM. However, modern browsers will leave the code in memory on the browser.

NotMe
  • 87,343
  • 27
  • 171
  • 245
  • 2
    facebook uses same method and keeping the code clean, so they dont get mixed up. a proper object oriented code would do a nice job, so no conflict comes in. – Basit Dec 26 '11 at 13:40
  • Modern browsers garbage collect. If references to the removed code are lost, it will become a candidate for garbage collection, eventually. – Ray Foss Feb 04 '14 at 15:02
  • @ray: "modern" in relation to my answer was 4 years ago.. GC wasn't very well done then; I honestly don't know if they are doing any better today. – NotMe Feb 04 '14 at 18:37
  • there is more complexity in the real world that "reevaluate your design" could possibly be generalised for. Architectures with mixins/traits/di, custom namespace solutions and other things could potentially need to exploit this kind of function. Reusable code, code injection/generation may require a class MyClass to be loaded, then altered in some way rendering the first in an SPA design out of date. An easy way would be to "unload" the class and add it again to the runtime. – JonathanC Dec 31 '20 at 14:02
11

No, you can't do that. Once a block of JavaScript gets loaded in the browser and executed, it gets stored in browser memory under the scope of the respective window. There is absolutely no way to unload it (without page refresh/window close).

Bo Persson
  • 90,663
  • 31
  • 146
  • 203
Usable Bytes
  • 119
  • 1
  • 2
  • You can fetch a js file, containing a class. You can load the class using eval and a closure like this //where js = 'class MyClass { }'; public load(context, js, classname) { js += `(function() { return new ${classname}();})()`; return function() { return eval(js); }.call(context); } just don't load it into document.head or body and eval (without using eval.call(context) – JonathanC Dec 31 '20 at 17:37
8

you can just namespace your code.. that way you prevent collisions

var MyJavaScriptCode = {};

MyJavaScriptCode.bla = function () {};

Orlando
  • 9,374
  • 3
  • 56
  • 53
  • Also be careful what you export. You can get a lot of control by using the module pattern: `window.someModule = (function () { /* build your module components here */ return { someComponent: myComponent, anotherComponent: myOtherComponent }; }())`. Of course, you should just use RequireJS or another library to offload unnecessary concerns. – Keen Jun 24 '14 at 16:03
5

It is possible to unload a javaScript file clearing the entire code from the browser. The steps are:

  1. Give an ID to the target "script" element (e.g. "mainJs", pointing to "main.js")
  2. Create another JS file (e.g "flush.js"), with the same functions and variables in "main.js", and make sure the functions and variables contents are empty.
  3. After "main.js" has been used up, we flush it by deleting the "script#mainJs" element and loading the "flush.js" dynamically into the DOM tree.

Example

mainJs    = document.getElementById("mainJs");
document.head.removeChild(mainJS);//Remooves main.js from the DOM tree

flushFile = document.createElement("script");
flushFile.setAttribute("src", "flush.js");
document.head.appendChild(flushFile);//Loads flush.js into the DOM tree, overwriting all functions and variables of main.js in browser memory to null

That's it

Starlyvil
  • 93
  • 1
  • 5
  • Hi brother. Thanks. The idea with the id is very good for identifying the certain file you want to exclude in case you were including same files multiple times !!! Thanks – Thanasis Jun 30 '19 at 08:46
3

Actually that's quite possible. You can replace an script or link element.

function createjscssfile(filename, filetype){
if (filetype=="js"){ //if filename is a external JavaScript file
  var fileref=document.createElement('script')
  fileref.setAttribute("type","text/javascript")
  fileref.setAttribute("src", filename)
}

else if (filetype=="css"){ //if filename is an external CSS file
  var fileref=document.createElement("link")
  fileref.setAttribute("rel", "stylesheet")
  fileref.setAttribute("type", "text/css")
  fileref.setAttribute("href", filename)
}
  return fileref
}

function replacejscssfile(oldfilename, newfilename, filetype){
var targetelement=(filetype=="js")? "script" : (filetype=="css")? "link" : "none" //determine element type to create nodelist using
var targetattr=(filetype=="js")? "src" : (filetype=="css")? "href" : "none" //determine corresponding attribute to test for
var allsuspects=document.getElementsByTagName(targetelement)
for (var i=allsuspects.length; i>=0; i--){ //search backwards within nodelist for matching elements to remove
    if (allsuspects[i] && allsuspects[i].getAttribute(targetattr)!=null && allsuspects[i].getAttribute(targetattr).indexOf(oldfilename)!=-1){
        var newelement=createjscssfile(newfilename, filetype)
        allsuspects[i].parentNode.replaceChild(newelement, allsuspects[i])
    }
  }
}

you must fill filename parameters as src attribute and filetype as "js" or "css"

I think there's no need to explain the code. Also you've posted in 2009 but hey. Maybe someone will need it right? :)

All credit goes to: http://www.javascriptkit.com/javatutors/loadjavascriptcss2.shtml

You can learn some tricks there btw.

st.
  • 579
  • 3
  • 11
  • 19
    Does this remove the code from browser memory, or just remove the reference in the html to the code? – random_user_name Apr 30 '12 at 20:11
  • 5
    @cale_b This does not remove it from browser's memory and thus does not make a sense to do that. – RN Kushwaha Sep 18 '15 at 07:36
  • 3
    Load another js file with the same function names with empty body which replaces the memory. Tested and its working. – Vignesh Bhaskar Sep 28 '16 at 19:12
  • doesn't seem to work to replace jQuery on the fly. Added a confirmation to the i=allsuspects.length loop. Then had it echo the currently loaded version to console, and it gives me 1.11.3, rather than the replacement 3.3.1 – mpag Oct 10 '18 at 18:13
  • @VigneshBhaskar this does not work in all cases. For example, if you are removing an SDK with one set of account keys and replacing it with the same SDK using a different set of account keys (via script src url parameter), it will not replace the existing implementation in memory. It will continue to run with the old initialization / old account keys. – Matthew Rideout Jun 09 '22 at 23:20
1

Exactly the similar requirement I've and I've tried in following way but it requires a small coding part from developer side even.

I've a js file with 20+ functions as below and file name is profile.js

function myprofile(){
//code block A
}  
function updateprofile(){
//code block B
}....
var functionsInJs=["myprofile","updateprofile",...]

Now I've written a method to clear the memory of this file as follows

function unloadJs(array){
    array.forEach(function(eachJsFn){
         window[eachJsFn]=undefined;//Clearing the functionality of js function in browsers window
    }
}

So, while to unload js functions i'll pass the array of function names in it.

Dharman
  • 30,962
  • 25
  • 85
  • 135
Vishnu Prasanth G
  • 1,133
  • 12
  • 12