Including js files from within js files

I’m working on an application which stores a lot of data in the application scope. Part of the data stored is a config CFC that has a method which loads ‘external assets’ (javascript and css files etc) into the <head> of the html document via <cfhtmlhead>. I love that tag :)

My part in this application development is limited to a particular section only, but there was already a lot of external assets present in the header and things were getting very messy. I was looking for a way to simulate <cfinclude> but from within a .js file so I could clean up my output a bit, fortunately there is a way!

I now have a master js file to add to the <head> section of my document:

<script src="js/master.js" type="text/javascript"></script>

From within this master.js file I can ‘include’ any js files I want.

master.js

//this function includes all necessary js files for the application
function include(file)
{

  var script  = document.createElement('script');
  script.src  = file;
  script.type = 'text/javascript';
  script.defer = true;

  document.getElementsByTagName('head').item(0).appendChild(script);

}

/* include any js files here */
include('js/myFile1.js');
include('js/myFile2.js');

The above code includes myFile1.js and myFile2.js, both of which are located in the relative ‘js/’ directory.

Not only does this clean up my output, but as my config file was stored in application scope every time I wanted to add/remove an asset from my application I need to refresh the scope…annoying. But now I am happy :)

Post a Comment or Leave a Trackback

36 Comments

  1. Kai
    December 7, 2006 at 11:29 pm | Permalink

    hola there! .-)
    Looks interesting. Did you check crossbrowser compatibility?
    Cheers, Kai

  2. December 8, 2006 at 1:35 am | Permalink

    Hi Kai,

    I’ve tested with success on:

    WinXP
    – Firefox 2.0
    – IE 6
    – IE 7
    – Netscape 8.1.2
    – Opera 9.0
    – Seamonkey 1.0.5

    Mac Tiger 10.4.6
    – Firefox 2.0
    – Safari 2.0.3

  3. December 8, 2006 at 3:32 am | Permalink

    That is a pretty nifty technique! I hear you on the clean output. Do you have any idea if this affects the ability for the browser to cache the included Javascript files? I assume it doesn’t as they are still just script tags, but just thought I would throw that out there.

    Excellent tip though!

  4. Kris John
    December 8, 2006 at 10:46 am | Permalink

    I use a similar technique and one problem i had -
    the function finishes before the javascript is actually loaded into the browser. so before calling any function in the included js file check if is loaded

    Cheers kris

  5. December 9, 2006 at 3:55 pm | Permalink

    Hi Kris,

    Interestingly I just ran across this issue when loading the scriptaculous framework. scriptaculous.js by default loads all the effects libraries, but it was throwing a ‘not defined’ error because those other libraries weren’t loaded yet!

    Oh well, it’s good to know the limitations of this technique so you know when you can and can’t use it.

    Thanks again

  6. matt snider
    December 11, 2006 at 6:57 pm | Permalink

    I use a similar solution, without the defer attribute, as i want the javascript to be parsed before the page ends. Have you noticed any benefit to defering?

    Michael, kris: I too have the problem where file B requires a function in file A, but file B is parsed before file A is completely loaded in memory. In my case obect in file B directly inherit from objects in file A, so i need a work around for this. Do either of you have a good work around for this?

    Also, you can always try the document.write() if the dom way fails. This will support a couple more of the older browsers.

  7. December 14, 2006 at 8:17 pm | Permalink

    Hello! I have some scripts files ” *.js “, but When I drag them to firefox, thei dont run, thei are listed!!!

    How can I install this files that I have on disk?

  8. Steve
    January 16, 2007 at 6:52 pm | Permalink

    What if I had a javascript file that was imbedded into deeper folders then the includes I wanted to access? So what I’m saying is there a way to include a .js file that is x folders up in the folder hierarchy?

    Your example looks like its relative as in in the samve folder as the .js itself

  9. January 16, 2007 at 10:05 pm | Permalink

    Hi Steve,

    Yes you can either use a Web Mapping (virtual directory) or use the ../ style notation.

    eg if my directory path was the following:

    C:\mps\dev\js\includes\js\master.js

    I could use this to reference a file in C:\mps\dev:

    include(‘../../../myJavascript.js’);

    or I could use a web mapping (myWebMapping points to C:\mps\dev):

    include(‘/myWebMapping/myJavascript.js’);

    Michael

  10. February 3, 2008 at 4:30 pm | Permalink

    not work on ie 6 ????

  11. March 21, 2008 at 6:45 pm | Permalink

    Does not work if your page is a frameset ( doing lots of fancy redirection calculations ) and has no head element!

  12. March 21, 2008 at 11:55 pm | Permalink

    @Garry – Hmm that would be quite a rare scenario I would imagine.

    Still, good to know. Thanks for the comment.

  13. March 28, 2008 at 2:10 pm | Permalink

    very nice tip ! was just looking for a solution for this problem .

  14. Alyas
    April 3, 2008 at 7:42 am | Permalink

    Great!, it helped me out… i was looking for something like this… Thanks.. keep it up

  15. Happy
    June 6, 2008 at 3:17 am | Permalink

    Nice tip, very interesting…

  16. June 6, 2008 at 2:44 pm | Permalink

    Good solution, although, out of interest, what would happen if you included two js files that themselves required the same (third) common js file included?

    As far as I can see, you would have to name the ‘include’ function differently in each js file, and you would end up with the script included twice.

  17. June 25, 2008 at 5:37 pm | Permalink

    Hi there i found your article looking for exactly this, your script is really nice but i had a problem when i tried to use it; the question is: when are you loading the functions include(‘whatever.js’)

    If i enter only the script as you show it, didn’t happens anything, i tried to put them into another function and load it in the onload event of the body and didn’t work again

    how do you load them??
    Cheers.

  18. June 25, 2008 at 5:41 pm | Permalink

    ejem, hehe sorry man, my problem wasn’t the loading of the functions, it was the relative location of the js files ;)

    i liked your code is a great and simple solution, as we said here in MX: está de guevos :D

  19. June 25, 2008 at 9:07 pm | Permalink

    Hi Juwe,

    Glad it worked out for you! Hello from sunny Australia :)

  20. June 26, 2008 at 10:07 pm | Permalink

    yeah thanks, i added your blog to my feed reader. Greetings from Mexico City. :P

    Cheers.

  21. Anthony Game
    November 23, 2008 at 8:35 am | Permalink

    It’s not working with IE7 (7.0.5730.11)

  22. Anthony Game
    November 23, 2008 at 8:47 am | Permalink

    It’s not working with IE7 (7.0.5730.11)

    Interesting info like:

    http://www.shauninman.com/archive/2007/04/13/operation_aborted

  23. Anthony Game
    November 23, 2008 at 8:52 am | Permalink

    see info for issue IE7
    http://www.shauninman.com/archive/2007/04/13/operation_aborted

  24. December 2, 2008 at 4:46 am | Permalink

    Hi! I tried your sample on Firefox 3 and IE 6. It’s not working. Are you sure you tried your code?

  25. December 2, 2008 at 6:05 am | Permalink

    @neldeo

    >Are you sure you tried your code?

    Err..pretty sure I did! But that was 2 years ago, way before FF3. I actually don’t use this technique anymore. I usually compress and combine my js (and css) files instead. Saves on http requests.

    Also from memory everything was fine in IE6

  26. Anthony Game
    December 2, 2008 at 7:44 pm | Permalink

    Tested again and again, sorry but your method is working PERFECT! It was another issue what created an error.

    So, it’s working neat and perfect over a range of IE6 … IE8b and of course all FFx.

    Thanks Michael!

  27. Isralennon
    December 10, 2008 at 11:36 pm | Permalink

    Quite a wonderful tip! Thanks a lot!

  28. February 17, 2009 at 3:43 pm | Permalink

    So, about the caching and server hits issue. If I include one file with the include function, would the browser hit the server file twice? or would the whole thing get cached? Would the included file get pulled down every time the page loads?

  29. Kiran
    April 22, 2009 at 7:01 am | Permalink

    Hi Michael Sharman,

  30. Kiran
    April 22, 2009 at 7:02 am | Permalink

    Hi Michael Sharman ,
    I Tried This Code. I Work Fine. Thnkx.

  31. April 23, 2009 at 7:05 am | Permalink

    Why using defer=true?
    That’s unnecessary and can lead to several errors if the script is not loaded in time…

    Anyway it’s a good script, I use a similar approach, the only difference being that I use a little loop that checks the script has not been already included before adding it.

  32. odame
    September 23, 2009 at 1:10 am | Permalink

    Great code! you have save my day. thank you

  33. ontue
    December 30, 2009 at 8:42 pm | Permalink

    Nice trick. I should have read your site eariler.

  34. chedie
    January 8, 2010 at 3:06 am | Permalink

    Hi!

    Finally, I found a solution to this issue! Great work! :D

    I have a question though. Is it possible to like having a “conditional” statement within this code? Example, I only want ’sample.js’ to load ONLY in ’specific web page’? I this question would really be a great addition to this great work. :D

    Hope to hear a reply soon. Thank you!

  35. Peter
    March 29, 2010 at 3:17 pm | Permalink

    Just terrific!

  36. July 2, 2010 at 9:12 am | Permalink

    Nice post. It is working fine. Thank you

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*