Dynamically removing/ replacing an external JavaScript or CSS file
Any external JavaScript or CSS file, whether added manually or dynamically, can be removed from the page. The end result may not be fully what you had in mind, however. I'll talk about this a little later.
Dynamically removing an external JavaScript or CSS file
To remove an external JavaScript or CSS file from a page, the key is to
hunt them down first by traversing the DOM, then call DOM's
removeChild()
method to do the hit job. A generic approach is to
identify an external file to remove based on its file name, though there are
certainly other approaches, such as by CSS class name. With that in mind, the
below function removes any external JavaScript or CSS file based on the file
name entered:
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
The function starts out by creating a collection out of either all
"SCRIPT
" or "LINK
" elements on the page depending
on the desired file type to remove.
The corresponding attribute to look at also changes accordingly ("src
" or
"href
" attribute). Then, the function sets out to loop through the gathered elements
backwards to see if any of them match the name of the file that should be
removed. There's a reason for the reversed direction- if/whenever an
identified element is deleted, the collection collapses by one element each
time, and to continue to cycle through the new collection correctly,
reversing the direction does the trick (it may encounter undefined
elements, hence the first check for allsuspects[i]
in the if
statement). Now, to delete the identified element, the DOM method
parentNode.removeChild()
is called on it.
So what actually happens when you remove an external JavaScript or CSS file? Perhaps not entirely what you would expect actually. In the case of JavaScript, while the element is removed from the document tree, any code loaded as part of the external JavaScript file remains in the browser's memory. That is to say, you can still access variables, functions etc that were added when the external file first loaded (at least in IE7 and Firefox 2.x). If you're looking to reclaim browser memory by removing an external JavaScript, don't rely on this operation to do all your work. With external CSS files, when you remove a file, the document does reflow to take into account the removed CSS rules, but unfortunately, not in IE7 (Firefox 2.x and Opera 9 do).
Demo: | "myscript.js" source: var petname="Spotty" |
"mystyle.css" source: #demotable td{ |
Dynamically replacing an external JavaScript or CSS file
Replacing an external JavaScript or CSS file isn't much different than
removing one as far as the process goes. Instead of calling
parentNode.removeChild()
, you'll be using
parentNode.replaceChild()
to do the bidding instead:
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]) } } } replacejscssfile("oldscript.js", "newscript.js", "js") //Replace all occurences of "oldscript.js" with "newscript.js" replacejscssfile("oldstyle.css", "newstyle", "css") //Replace all occurences "oldstyle.css" with "newstyle.css"
Notice the helper function createjscssfile()
, which is
essentially just a duplicate of loadjscssfile()
as seen on the previous
page, but modified to return the newly created element instead of actually
adding it to the page. It comes in handy when
parentNode.replaceChild()
is called in replacejscssfile()
to replace the old element with the new. Some good news here- when you
replace one external CSS file with another, all browsers, including IE7,
will reflow the document automatically to take into account the new file's
CSS rules.
Demo: | "oldscript.js" source: var petname="Spotty" "newscript.js" source: var petname="Beauty" |
"oldstyle.css" source: #demotable2 td{ "newstyle.css" source: #demotable2 td{ |
Conclusion
So when is all this useful? Well, in today's world of Ajax and ever larger web applications, being able to load accompanying JavaScript/ CSS files asynchronously and on demand is not only handy, but in some cases, necessary. Have fun finding out what they are, or implementing the technique. :)
- Dynamically removing an external JavaScript or CSS file
- Dynamically removing/ replacing external JavaScript and CSS files, conclusion