Before we start this discussion, I’d like to point out that while dynamically inserting JavaScript and CSS can easily be done with PHP, or your server-side scripting language of choice, those solutions don’t apply to static HTML pages (what? static pages? what are those?), and I came across a situation where I needed a non-PHP solution.
On my personal website, I have a single static page, my home page. This page does nothing but provide links to the rest of my site, and as such, it does not need to be PHP driven with all the bells and whistles that go with it. Just some clean code, and some clean CSS to make it pretty. Recently I found a small JavaScript snippet that I wanted on my home page, so I added it, and it looked good. The trouble is that it’s a seasonal script, and it makes no sense to leave it on all year. So instead of editing my page twice a year to add and remove this script, I figured I could go one better and dynamically add the script to my page via JavaScript. After a quick search I found Dynamically Loading External JavaScript Files which has a couple of methods listed to do this. After looking them over, I decided the DHTML method would suit my needs better.
Here is that method:
function load_script(url) {
var e = document.createElement("script");
e.src = url;
e.type = "text/javascript";
document.getElementsByTagName("head")[0].appendChild(e);
}
All this does is create a <script> tag, populate it with our data, and insert it into the head of the page. This works beautifully, but only after some of the page has been loaded already. And what better way to make sure that some of the page has been loaded than with the window.onload event?
window.onload = function( ) {
var date = new Date;
var month = date.getMonth( ) + 1; // +1 due to index 0
// we only want this run between october and march
if ((10 <= month) || (3 >= month)) {
load_script("scripts/winter/seasonal_script.js");
}
}
So now I have my seasonal script running only during the winter months.
But I’ve done something horrible, and you may have caught it… I just killed any previously set window.onload function. To remedy this, you can choose from a couple of different approaches:
- Use JavaScript’s addEventListener function to append your function to the window.onload event
- Store any previous window.onload event in a variable and then re-insert it into the function
I chose to use the latter for this because for some reason or another, I couldn’t get the addEventListener function to work properly. Here is my modified code to reflect this change:
var prevLoad = window.onload; // store any previous window.onload event
window.onload = function( ) {
// test and make sure it was a valid function, and if so, run it here
if ("function" == typeof prevLoad) {
prevLoad( );
}
var date = new Date;
var month = date.getMonth( ) + 1; // +1 due to index 0
// we only want this run between october and march
if ((10 <= month) || (3 >= month)) {
load_script("scripts/winter/seasonal_script.js");
}
}
That solves that problem.
One other thing that this script needs, is it uses a CSS file to style some of the effects that it’s running, and that style sheet is in my <head> tag with the rest of my style sheets. But I now only need it during the winter months, and the rest of the year, it’s just moldy bandwitch.
To remedy this, I took a look at the load_script function and it hit me… it’s basically the same thing, a tag loaded in the head of the page. So I modified the function:
function load_css(url) {
var e = document.createElement("link");
e.href = url;
e.type = "text/css";
e.rel = "stylesheet";
e.media = "screen";
document.getElementsByTagName("head")[0].appendChild(e);
}
Now I have two functions that supplement each other quite nicely, and a snippet of code to place them in to make the whole shebang work and download the stuff I need, only when I need it.
Now we just add the new function into the script and we get the following:
var prevLoad = window.onload;
window.onload = function( ) {
if ("function" == typeof prevLoad) {
prevLoad( );
}
var date = new Date;
var month = date.getMonth( ) + 1; // +1 due to index 0
// we only want this run between october and march
if ((10 <= month) || (3 >= month)) {
load_css("scripts/winter/seasonal_style.css");
load_script("scripts/winter/seasonal_script.js");
}
}
And there you have it, dynamically loaded JavaScript and CSS and not a drop of PHP to be found. The great part is, because this is all run only when we need it, it degrades gracefully as well (provided you’re not using it to load something required all the time).
A couple of gotcha’s I discovered while using this method: I was trying to dynamically load a script that had some required HTML to go with it, and I thought, what better way to dynamically load HTML than with jQuery. Well… it turns out that if you load jQuery with this method, you can’t actually use jQuery from within the window.onload function itself, you need to pull in another JavaScript file and use it there. I’m not exactly sure why, but my hunch is that it doesn’t load up jQuery until after the window.onload function is done running, and by that time, it’s too late. My solution was the following:
var prevLoad = window.onload;
window.onload = function( ) {
if ("function" == typeof prevLoad) {
prevLoad( );
}
load_css("scripts/style.css");
load_script("http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js");
load_script("scripts/build_html.js");
load_script("scripts/run_script.js");
}
This way, the CSS is loaded and ready for the script, then we pull in jQuery, build our required HTML, and then run the script. Nothing gets left out, and we can run any kind of logic before hand to determine if we want to run this script or not. And if not, there is nothing left behind in our code to take up bandwidth, or otherwise make it ugly.














