37

I have seen Scriptaculous.js file to include its required javascript files dynamically. Is there any better approach to include javascript dynamically.

For example, I would like to include my js files like,

<script src="single.js?files=first.js,second.js,third.js..."></script>

How can I do that in an efficient manner?

Rob W
  • 315,396
  • 71
  • 752
  • 644
Nazmul
  • 6,658
  • 12
  • 49
  • 61
  • 4
    Why negative voting?What's wrong with it? – Nazmul Apr 22 '11 at 02:12
  • @Hoque - it *looks* like someone is going through the question page and downvoting everything; there's at least 5 questions in a row with -1 or lower. I'm guessing a moderator could verify this... – John Rasch Apr 22 '11 at 02:15
  • 2
    Agree, I was also curious what's happening. Seems like some spammer is having a fun. So... +1 to compensate. – Damb Apr 22 '11 at 02:16
  • I wonder there are three arswers here, but I am getting only two. What is going on? – Nazmul Apr 22 '11 at 02:19
  • @Hoque - one was spam and deleted. I believe the answer count is cached or possibly just includes deleted answers (i.e. a bug). – John Rasch Apr 22 '11 at 02:21
  • You might want to investigate [RequireJS](http://requirejs.org/) or [LabJS](http://labjs.com) – Pointy Apr 22 '11 at 02:38
  • Possible duplicate of [JQuery to load Javascript file dynamically](http://stackoverflow.com/questions/912711/jquery-to-load-javascript-file-dynamically) – Michał Perłakowski Dec 26 '15 at 12:22

9 Answers9

46

To load a .js or .css file dynamically, in a nutshell, it means using DOM methods to first create a swanky new "SCRIPT" or "LINK" element, assign it the appropriate attributes, and finally, use element.appendChild() to add the element to the desired location within the document tree. It sounds a lot more fancy than it really is. Lets see how it all comes together:

function loadjscssfile(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)
 }
 if (typeof fileref!="undefined")
  document.getElementsByTagName("head")[0].appendChild(fileref)
}

loadjscssfile("myscript.js", "js") //dynamically load and add this .js file
loadjscssfile("javascript.php", "js") //dynamically load "javascript.php" as a JavaScript file
loadjscssfile("mystyle.css", "css") ////dynamically load and add this .css file

i hope its use full

Anand Thangappan
  • 3,000
  • 2
  • 25
  • 31
13

You can use the jQuery.getScript() function... I think it will be much easier to you with this to include a JavaScript .js file.

Here is the reference.

Community
  • 1
  • 1
Vivek
  • 10,426
  • 14
  • 44
  • 65
3

Following the advice of Salaman A's comments, I found how Google does it now with Analytics: https://developers.google.com/analytics/devguides/collection/gajs/asyncTracking

And here is a more generic version of the same code:

(function() {
    var s = document.createElement('script'); // Create a script element
    s.type = "text/javascript";               // optional in html5
    s.async = true;                           // asynchronous? true/false
    s.src = "//example.com/your_script.js"; 
    var fs = document.getElementsByTagName('script')[0];  // Get the first script
    fs.parentNode.insertBefore(s, fs);
})();
Community
  • 1
  • 1
Luke
  • 14,840
  • 10
  • 84
  • 92
3

EDIT: DON'T USE THIS METHOD - I wrote this anwer a decade ago!

Leaving it here purely for posterity.


there are many different ways, but the way Google loads additional scripts is like this:

function getScript(src) {
    document.write('<' + 'script src="' + src + '"' +
                   ' type="text/javascript"><' + '/script>');
}

This is taken directly from Google maps loader.

Writing a script tag directly to the document is the simplest and most efficient way.

herostwist
  • 3,362
  • 1
  • 22
  • 32
  • 4
    Google itself does not recommend it anymore :) for example they've changed the recommended way of adding google analytics code to websites. – Salman A Apr 23 '11 at 07:06
  • 1
    could you provide a link to back that up as all google's apis are loaded this way, even http://code.google.com/apis/loader/ – herostwist Apr 23 '11 at 07:30
  • 2
    There you go: [Using the Traditional Snippet](http://code.google.com/apis/analytics/docs/tracking/gaTrackingOverview.html). Read the introductory paragraph that says _we recommend that you use the default tracking code snippet, described in Tracking Sites_. The legacy script (script loader to be more precise) uses `document.write`, the updated script uses `document.createElement`. Here is another interesting read: [Avoid document.write](http://code.google.com/speed/page-speed/docs/rtt.html#AvoidDocumentWrite) – Salman A Apr 23 '11 at 10:40
  • interesting read. you only really gain when you load scripts asynchronously this way, which is fine if you use a callback. I guess it depends if you need your scripts loaded in a curtain order. – herostwist Apr 23 '11 at 17:05
  • 2
    LOL thanks for the downvote 3 1/2 years after the answer - unsurprisingly things have moved on since I wrote this answer. – herostwist Sep 18 '14 at 10:49
  • @herostwist you need to update every single answer you post on a regular basis!! Everybody else does it hahaha :P – GôTô Jan 14 '16 at 14:08
  • This blows away any other HTML on the page... not good – bdombro Mar 01 '21 at 17:51
1

document.getElementsByTagName("head")[0].appendChild(fileref‌​) is not working if you have some document.ready() works inline. $("head").append(fileref); works great for me, although it needs jquery.min.js inline reference.

<head>
    <!-- Meta, title, CSS, favicons, etc. -->
    <script src="script/jquery.min.js"></script>
    <script src="script/master_load.js"></script>
    <script>
        load_master_css();
        load_master_js();
    </script>
</head>

and master_load.js :

function loadjscssfile(filename) {
    if (filename.substr(filename.length - 4) == ".css") { // 'endsWith' is not IE supported.
        var fileref = document.createElement("link")
        fileref.setAttribute("rel", "stylesheet")
        fileref.setAttribute("href", filename)
        //fileref.setAttribute("type", "text/css")
    }
    else if (filename.substr(filename.length - 3) == ".js") {
        var fileref = document.createElement('script')
        fileref.setAttribute("src", filename)
        //fileref.setAttribute("type", "text/javascript")
    }
    $("head").append(fileref);
}
function load_master_css() {
    loadjscssfile("css/bootstrap.min.css");
    // bunch of css files
}
function load_master_js() {
    loadjscssfile("script/bootstrap.min.js");
    // bunch of js files
}
1

To add a new javascript file dynamically:

function includeJS(jsFile) {
    $('head').append($('<script>').attr('type', 'text/javascript').attr('src', jsFile));
}


// Pick a JS to load
if ($.browser.msie) {
    includeJS('first.js');
} else {
    includeJS('second.js');
}
includeJS('third.js');
Justin808
  • 19,126
  • 41
  • 143
  • 241
1

I've seen what the scriptaculous loader does. What it does is that it goes through all script tags in the document to find the one that loaded itself, e.g:

<script src="/path/to/single.js?files=first.js,second.js,third.js"></script>

Then it parses the querystring used inside the src attribute and dynamically create additional script tags for each script file. At the same time it also parses the path of the base script (/path/to/single.js) and uses the same path to load dependency files (e.g. /path/to/first.js).

You can create your own script loader like this. In vanilla javascript, you can use the following functions:

Anand Thangappan has posted a solution that uses these functions. If you're using a framework such as jQuery or MooTools then both provide their own implementations of dynamically loading JsvaScript.

Finally, there is a server side solution for your problem. Look at minify -- Combines and minifies multiple CSS or JavaScript files into a single download.

Salman A
  • 229,425
  • 77
  • 398
  • 489
0

We can quickly extend this so that a callback can be performed once the script is added.

function loadjscssfile(filename, filetype, callback){
    if (typeof fileref!="undefined") {
        document.getElementsByTagName("head")[0].appendChild(fileref);
        callback();
    }
}
Phillip Senn
  • 43,069
  • 83
  • 242
  • 359
  • I doubt this works at all... You pass `filename` and `filetype` which you don't use and use `fileref` which you don't declare... – GôTô Jan 14 '16 at 14:10
  • Sorry, my comment was in reference to Anand Thangappan's answer above. I though i had made this a comment on that, not a new answer. – Dennis Bartlett Apr 05 '16 at 18:04
0

Create a script tag, set the URL, add it to the document:

let script = document.createElement("script");
script.src = "https://example.com/your_script.js"; 
document.body.appendChild(script);

That's it. There are too many overly complicated answers on this page for such a simple task.

If you're using modern JavaScript, you can use dynamic importing with a syntax like await import(...). That's out of the scope of this answer, but you can read more about that here.

vageko4924
  • 21
  • 1