views:

990

answers:

3

Hello,

I am using prototype to load external js file (actually it is php file) dynamically. Like this:

function UpdateJS(file)
{
  var url    = 'main_js.php?file='+file;
  var myAjax = new Ajax.Request( url, {method: 'get', onComplete: showResponseHeader} );
}
function showResponseHeader (originalRequest) 
{
  $('jscode').innerHTML = originalRequest.responseText;
}

Container "jscode" is defined like this:

<script type="text/javascript" id="jscode"></script>

And it works! But if some different file is called, all the functions from previous one are preserved. And I don't want that. Anybody knows how to "unload" first js file when second one is called?

(I also tried using Ajax.Updater function but the result is the same.)

Update: It turns out that there is bigger problem: it only loads if function "UpdateJS" is in window.onload that is why it doesn't load anything else after that. So prototypes update it's maybe not such a good way for this...

+1  A: 

I don't think you can unload a set of properties defined within the scope of a file. A workaround would be to define the functions contained in each file in a central object that you scrap (or override) whenever you want to get rid of it.

Theo.T
+2  A: 

There's a great tutorial on how to dynamically unload Javascript and CSS here:

http://www.javascriptkit.com/javatutors/loadjavascriptcss2.shtml

The below code is borrowed from the above link, it is a pure JS solution, not a Prototype JS one, but should do the trick:

function removejscssfile(filename, filetype){
 var targetelement=(filetype=="js")? "script" : (filetype=="css")? "link" : "none" //determine element type to create nodelist from
 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(filename)!=-1)
   allsuspects[i].parentNode.removeChild(allsuspects[i]) //remove element by calling parentNode.removeChild()
 }
}

removejscssfile("somescript.js", "js") //remove all occurences of "somescript.js" on page
removejscssfile("somestyle.css", "css") //remove all occurences "somestyle.css" on page

If you don't need the CSS removing functionality, I'm sure you can hack it away.

karim79
I had a read about this as well, the problem seems to be that it removes the script node, but not actually the defined properties from the memory, and that was the point wasn't it ?
Theo.T
No, actually it's not. But yes, I thought that that was the problem. If my new .js file loads function which has the same name as in the first .js file it will use the second one and that is what I wanted.
domagoj412
A: 

HI MAN DO THIS:

function UpdateJS(file)
{
  $('jscode').innerHTML = '';  /*YOU NEED TO RESET THIS*/
  var url    = 'main.js'; /*YOU CAN USE A JAVASCRIPT FILE*/
  var myAjax = new Ajax.Request( url, {method: 'get', onComplete: showResponseHeader} );
}
function showResponseHeader (originalRequest) 
{
  $('jscode').innerHTML = originalRequest.responseText;
}
jamspeedy3