Dynamically Including JavaScript and CSS Files

In C/C++, if you want to include code from another file, you use the #include directive. In PHP, you use the require or include command. In Java and Python, you use the import command to import a library. In Perl, you use the require or use command. However in JavaScript, for some reason, it doesn’t have this functionality. :(

What is expected in JavaScript is that you do the includes externally on the HTML page using the script-src tag. But there are many limitations with this option. Wouldn’t it be nice if you can simply perform includes just like you do it in other languages?

Fortunately, there is a workaround!

What you do is dynamically create the script tag element at runtime in the DOM. Below is a JavaScript function where you simply call whenever you need to include a JavaScript src file.

function includeJavascript(src) {
    if (document.createElement && document.getElementsByTagName) {
        var head_tag = document.getElementsByTagName('head')[0];
        var script_tag = document.createElement('script');
        script_tag.setAttribute('type', 'text/javascript');
        script_tag.setAttribute('src', src);
        head_tag.appendChild(script_tag);
    }
}
// Include javascript src file
includeJavascript("http://www.mydomain.com/script/mynewscript.js");

The idea behind this is that a new script-src tag is dynamically constructed in the DOM at runtime. It will be like adding this line to the <head> section of the web page but dynamically:

<script type="text/javascript"
   src="http://www.mydomain.com/script/mynewscript.js">
</script>

The same idea can be applied to CSS files. Below is a function where you can include CSS files programmatically.

function includeCSSfile(href) {
    var head_node = document.getElementsByTagName('head')[0];
    var link_tag = document.createElement('link');
    link_tag.setAttribute('rel', 'stylesheet');
    link_tag.setAttribute('type', 'text/css');
    link_tag.setAttribute('href', href);
    head_node.appendChild(link_tag);
}
About these ads

8 thoughts on “Dynamically Including JavaScript and CSS Files

  1. Mybrid

    “It will be like adding this line to the section of the web page but dynamically:”

    Question? Would it really? My limited understanding of the Javascript parser is that this include is visible to those pieces of the DOM after invocation of the enclosing routine?

    I think the earliest Javascript invocation is in the “onLoad” event for the body tag? If you were to put the include farther down the DOM, say in some lower div tag, then the routines would not be visible until that div tag got parsed? right?

    I believe this is how the browser is able to “render as you go” where pieces of the page can be rendered without the following content being inspected. Sort of a stream; the way GZIP can do it things in chunks independent of what comes after.

    So, in order for your statement to be completely correct I think you’d want to make sure your include happened at the earliest possible invocation? No? The “onLoad” event for the body tag? In other words, even though the code is specifying the “head” I do not believe it gets parsed at the time the other “head” code is parsed? If I’m wrong, please let me know! Wouldn’t be the first time, eh? I think your routine is great though for a nice body “onLoad” event. You don’t have to specify in the HEAD section any includes at all. Another twist on this would be on the server side. I wrote a Perl script that took various Javascript files and compiled them into one script dynamically based upon input parameters. Sort of dynamic “include” of a bunch of files that all got mashed into the output of one include. However, doing this from within Javascript on the server would be cool. Self modifying code! Wooo hooo!

    Speaking of GZIP. most web sites compress content using GZIP? I think Schwab ran into trouble with this and inlined Javascript where the loading of the code crossed the GZIP size barrier and therefore partial Javascript was being uncompressed and failing to compile because the remaining code was in a following chunk?

    Unless you have over 18KB in your Javascript file or some crazy size then its probably not a problem. But I’m not sure the claim of the dynamic include being like the static include applies to chunking, i.e. you may run into chunking problems with the routine you have and not necessarily with the “head” section stuff.

    What I find problematic with Javascript is that invocation happens interleaved with parsing HTML snippets. Each Javascript invocation is kinda of its own island, making code reuse problematic. Can you guarantee the “include” on one island will always be there for another island of code? If not you might want to be defensive and “include” everywhere one uses.

    Javascript programming is just ugly.

    Reply
  2. Alvin Abad Post author

    Mybrid,

    Thanks for your comments. My apologies if the descriptions were not clear in my posting.

    “…this include is visible to those pieces of the DOM after invocation of the enclosing routine?”

    Yes, you are correct. Everything still happens at runtime and sequentially. This is not a static include like those constructed on the server-side. That is why I said, “a new script-src tag is dynamically constructed in the DOM at runtime.”

    “even though the code is specifying the “head” I do not believe it gets parsed at the time the other “head” code is parsed?”

    Yes and no. It will all depend where and when you call the includeJavascript() function. [1] If you define and call the function in the head section, then it will be parsed together with the other scripts in the head. If you call the function anywhere in the body then the script-src tag and the execution of the dynamically included javascript will only happen at that time.

    I used the head node (as the parent node to append the script-src tag) simply as a place holder and not necessarily meant to imply that it will be there already when the head node is parsed. In the absence of a known existing parent node to append the new script node, I thought the head node is the most logical choice since that node is created early on in the DOM. The head node as a parent node is probably a bad example (my bad) because it doesn’t really matter what the parent node is. The idea is to create a new script node in the DOM, and when it does get created, its javascript source is executed.

    Thanks again for dropping by and commenting!

    Alvin

    [1] I said “when” because you can insert and execute new javascripts dynamically at a much later time, even after the document has completely loaded. This is what I do in lieu of XMLHttpRequest() if I need to do cross-site scripting. But that’s another story. That’s probably a good blog topic to write about. :)

    [2]

    Here’s a sample demo.
    http://alvin.boldlygoingnowhere.org/tmp/testJavaScript.html

    Reply
  3. Mybrid

    OK, thanks!

    “It will be like adding this line to the ‘head’ section of the web page but dynamically.”

    Ok, so my understanding was based upon a literal reading of this sentence but as you pointed out, you already considered the dynamic nature, previously.

    Reading is such ardous work! Hoo ahhh!

    “It is the mark of an educated mind to rest satisfied with the degree of precision which the nature of the subject admits and not to seek exactness where only an approximation is possible.”
    –Aristotle

    Reply
  4. Mybrid

    “It will be like adding this line to the ‘head’ section of the web page but dynamically.”

    Now I see, the word dynamically can be taken one of two ways.

    1.) Dynamic mechanism for adding but otherwise exactly the same as a static include, Mybrid’s interpretation.

    2.) Disclaimer, whereby the ‘but’ infers the addition is the same except for the dynamic behavior, Alvin’s intent I believe. “It will be like adding this line to the ‘head’ section of the web page except for the properties inherent to anything added to the DOM dynamically at run time.”

    Reply
  5. Pingback: Including JavaScript Source File into OpenSocialDevApp or Google’s Coderunner « Alvin Abad Boldly Going Nowhere

  6. lun ashis

    I tried using the above one but i am having some problem. I can’t see the added script tags in header section of the page after adding dynamically. it displays the tages when i do $$(‘head’)[0].innerHTML, otherwise not.

    Can you tell me why is this ?

    Reply
    1. Alvin Abad Post author

      >I can’t see the added script tags in header section of the page after adding dynamically.

      How were you doing this? Were you using “view source” of the browser? You won’t see it this way because the changes in the DOM happened after loading. You would need another tool like Firebug to view the current state of the DOM.

      Hope this helps.

      Alvin

      Reply
  7. Magdalena

    It is actually a great and helpful piece of info. I’m satisfied that you shared this helpful info with us. Please keep us informed like this. Thank you for sharing.

    Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s