85

I am appending the jQuery library to the dom using:

 var script = document.createElement('script');
 script.src = 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js';
 script.type = 'text/javascript';
 document.getElementsByTagName('head')[0].appendChild(script);

However when I run:

jQuery(document).ready(function(){...

The console reports the error:

Uncaught ReferenceError: jQuery is not defined

How do I load jQuery dynamically as well as use it once it is in the dom?

ThomasReggi
  • 42,912
  • 63
  • 199
  • 343
  • 2
    Is there a reason you are wanting to do this vs the more optimized way? – Code Maverick Apr 11 '12 at 20:24
  • Some answers in this question may help you - http://stackoverflow.com/questions/7474354/include-jquery-in-the-javascript-console – mrtsherman Apr 11 '12 at 20:26
  • @Scott Yes. I have an application in which at installation it loads both jquery as well as a script. I need to load jquery within the script so that jquery does not break the users themes. I need to conditionally load javascript onto a certain webpage within their theme. Please just trust me on this. – ThomasReggi Apr 11 '12 at 20:28
  • Why would jQuery break the users' themes? If loading jQuery (which has no effect on css) can break themes, you're doing something very wrong. – Anders Marzi Tornblad Apr 11 '12 at 20:35
  • Good point, but, What if they are using an older version of jQuery or another library? – ThomasReggi Apr 11 '12 at 20:42
  • @ThomasReggi - I think it would behoove you to explain how your application works with these "user themes" and possible duplicate versions of jQuery or other libraries. – Code Maverick Apr 11 '12 at 20:44
  • Different versions of jQuery can actually live side-by-side in the same web page: http://stackoverflow.com/questions/528241/how-do-i-run-different-versions-of-jquery-on-the-same-page – Anders Marzi Tornblad Apr 11 '12 at 20:58
  • Possible duplicate of [Dynamically load a JavaScript file](http://stackoverflow.com/questions/21294/dynamically-load-a-javascript-file) – Michał Perłakowski Dec 26 '15 at 12:26

8 Answers8

141

There's a working JSFiddle with a small example here, that demonstrates exactly what you are looking for (unless I've misunderstood your request): http://jsfiddle.net/9N7Z2/188/

There are a few issues with that method of loading javascript dynamically. When it comes to the very basal frameworks, like jQuery, you actually probably want to load them statically, because otherwise, you would have to write a whole JavaScript loading framework...

You could use some of the existing JavaScript loaders, or write your own by watching for window.jQuery to get defined.

// Immediately-invoked function expression
(function() {
    // Load the script
    var script = document.createElement("SCRIPT");
    script.src = 'https://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js';
    script.type = 'text/javascript';
    script.onload = function() {
        var $ = window.jQuery;
        // Use $ here...
    };
    document.getElementsByTagName("head")[0].appendChild(script);
})();

Just remember that if you need to support really old browsers, like IE8, load event handlers do not execute. In that case, you would need to poll for the existance of window.jQuery using repeated window.setTimeout. There is a working JSFiddle with that method here: http://jsfiddle.net/9N7Z2/3/

There are lots of people who have already done what you need to do. Check out some of the existing JavaScript Loader frameworks, like:

Anders Marzi Tornblad
  • 17,122
  • 9
  • 50
  • 62
  • This solution works, except for in WordPress. Any way this can be modified to load jQuery into a different object ? – Kraang Prime Dec 20 '14 at 18:14
  • @SanuelJackson With Wordpress, you should use the `wp_enqueue_script()` function to include jQuery properly. Documentation: http://codex.wordpress.org/Function_Reference/wp_enqueue_script Some more information here: http://digwp.com/2009/06/including-jquery-in-wordpress-the-right-way/ or here: http://digwp.com/2011/09/using-instead-of-jquery-in-wordpress/ – Anders Marzi Tornblad Dec 22 '14 at 09:45
  • Yes, what I was saying is that the above code does not work on Wordpress because it loads jQuery asyncronously as well. Even if this script is loaded at the very bottom of the page (just before closing html), jQuery isn't fully 'initialized' and thus it sees no jQuery loaded, and continues to load and do the callback. Once loaded, it buggers up other things that were loaded async that depended on jQuery being loaded a different way (eg $, jQuery, etc), or dependant on a different version of jQuery. – Kraang Prime Dec 22 '14 at 10:53
  • It is great in the other cases I tried. Was just making a note of the only glaring problem with this. If somehow it could be tuned, but i don't think it is possible as it depends on detecting jQuery, which of course isn't loaded, and thus can only proceed with the logic of - if no jquery ... then .. – Kraang Prime Dec 22 '14 at 10:56
  • @atornblad can you help me to resolve the issue? At my it is working perfect in most of the cases as suggested by AWolf . But when require js or any other library used in 3rd party website then create conflict issue. so i want to use noconflict and change the $ and jQuery vaialbe in css. Check my link http://stackoverflow.com/questions/28678039/load-jquery-dynamically-before-using-jquery/28678607 – Yatin Mistry Feb 27 '15 at 09:55
  • I've seen code that sets `script.async = true;`, and I hoped that setting it to `false` would make it so it doesn't continue with the current script until jQuery loads, like the simple but apparently dangerous `document.write` does. – Agustín Lado Jul 13 '16 at 16:30
  • 1
    You don't need to do the polling, you can use only one line to wait until jquery loads using the .onload event like http://stackoverflow.com/a/42013269/3577695 – aljgom Feb 02 '17 at 22:18
  • The question *(and the original answer)* is from 2012, when people still unfortunately had to deal with IE8, which did not support the `load` event (http://stackoverflow.com/questions/4845762/onload-handler-for-script-tag-in-internet-explorer). Thank you for the downvote, pointing out that five years have passed. I have updated my answer. – Anders Marzi Tornblad Feb 03 '17 at 08:56
  • In order to get jquery working, I had to change the "appendChild" to "prepend" !!! – Diego Favero May 26 '19 at 14:47
  • Warning: the example script uses a really OUTDATED jQuery version from 5 years ago. The most recent version is 3.4.1 – poitroae Jan 12 '20 at 03:39
  • Yes, both the question and the answer are from 2012. – Anders Marzi Tornblad Jan 14 '20 at 13:54
7

There is an other way to load jQuery dynamically (source). You could also use

document.write('<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"><\/script>');

It's considered bad practice to use document.write, but for sake of completion it's good to mention it.

See Why is document.write considered a "bad practice"? for the reasons. The pro is that document.write does block your page from loading other assests, so there is no need to create a callback function.

Community
  • 1
  • 1
Jacob van Lingen
  • 6,165
  • 3
  • 39
  • 68
  • 1
    I read the document you linked to, and for my use case of loading an older jQuery library for IE8, using document.write seems to be ok. It's working well for me so far. – Alan Aug 20 '14 at 01:03
  • This is the easiest most straightforward way to do this. Would there be a problem doing this at the beginning of a rather large script which is a separate JS file? It's too good to pass up. – Agustín Lado Jul 13 '16 at 16:27
6

Encosia's website recommends:

<script type="text/javascript" 
        src="http://www.google.com/jsapi"></script>
<script type="text/javascript">
  // You may specify partial version numbers, such as "1" or "1.3",
  //  with the same result. Doing so will automatically load the 
  //  latest version matching that partial revision pattern 
  //  (e.g. 1.3 would load 1.3.2 today and 1 would load 1.7.2).
  google.load("jquery", "1.7.2");

  google.setOnLoadCallback(function() {
    // Place init code here instead of $(document).ready()
  });
</script>

But even he admits that it just doesn't compare to doing the following when it comes to optimal performance:

    <script src="//ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.min.js" type="text/javascript"></script>
    <script type="text/javascript"> window.jQuery || document.write('<script src="js/libs/jquery-1.7.2.min.js">\x3C/script>')</script>
    <script type="text/javascript" src="scripts.js"></scripts>
</body>
</html>
Code Maverick
  • 19,231
  • 10
  • 57
  • 111
  • I can only load one javascript. This would mean I'd have to load google jsapi dynamically then from with that load jquery? Seems redundant for my use case. – ThomasReggi Apr 11 '12 at 20:33
  • 1
    This is what a jQuery loader does. You reference the loader and the loader injects jQuery into the document for you. – Code Maverick Apr 11 '12 at 20:38
3

You need to run your code AFTER jQuery finished loading

var script = document.createElement('script'); 
document.head.appendChild(script);    
script.type = 'text/javascript';
script.src = "//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js";
script.onload = function(){
    // your jQuery code here
} 

or if you're running it in an async function you could use await in the above code

var script = document.createElement('script'); 
document.head.appendChild(script);    
script.type = 'text/javascript';
script.src = "//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js";
await script.onload
// your jQuery code here

If you want to check first if jQuery already exists in the page, try this

aljgom
  • 4,765
  • 1
  • 23
  • 22
0

HTML:

<html>
  <head>

  </head>
  <body>

    <div id='status'>jQuery is not loaded yet.</div>
    <input type='button' value='Click here to load it.' onclick='load()' />

  </body>
</html>   

Script:

   <script>

        load = function() {
          load.getScript("jquery-1.7.2.js");
          load.tryReady(0); // We will write this function later. It's responsible for waiting until jQuery loads before using it.
        }

        // dynamically load any javascript file.
        load.getScript = function(filename) {
          var script = document.createElement('script')
          script.setAttribute("type","text/javascript")
          script.setAttribute("src", filename)
          if (typeof script!="undefined")
          document.getElementsByTagName("head")[0].appendChild(script)
        }

        </script>
coder
  • 14,595
  • 32
  • 107
  • 213
0

The reason you are getting this error is that JavaScript is not waiting for the script to be loaded, so when you run

jQuery(document).ready(function(){...

there is not guarantee that the script is ready (and never will be).

This is not the most elegant solution but its workable. Essentially you can check every 1 second for the jQuery object ad run a function when its loaded with your code in it. I would add a timeout (say clearTimeout after its been run 20 times) as well to stop the check from occurring indefinitely.

var jQueryIsReady = function(){
    //Your JQuery code here
}

var checkJquery = function(){
    if(typeof jQuery === "undefined"){
        return false;
    }else{
        clearTimeout(interval);
        jQueryIsReady();
    }
}
var interval = setInterval(checkJquery,1000);
marteljn
  • 6,140
  • 2
  • 28
  • 42
0

Using require.js you can do the same thing in a safer way. You can just define your dependency on jquery and then execute the code you want using the dependency when it is loaded without polluting the namespace:

I generally recommend this library for managing all dependencies on Javascript. It's simple and allows for an efficient optimization of resource loading. However there's some precautions you may need to take when using it with JQuery . My favourite way to deal with them is explained in this github repo and reflected by the following code sample:

<title>jQuery+RequireJS Sample Page</title>
   <script src="scripts/require.js"></script>
   <script>
   require({
       baseUrl: 'scripts',
       paths: {
           jquery: 'https://ajax.googleapis.com/ajax/libs/jquery/1.6.0/jquery.min'
       },
       priority: ['jquery']
    }, ['main']);
    </script>
txominpelu
  • 1,067
  • 1
  • 6
  • 11
0

From the DevTools console, you can run:

document.getElementsByTagName("head")[0].innerHTML += '<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"><\/script>';

Check the available jQuery version at https://code.jquery.com/jquery/.

To check whether it's loaded, see: Checking if jquery is loaded using Javascript.

kenorb
  • 118,428
  • 63
  • 588
  • 624