8

At my website, I am loading jQuery asynchronously.

In order to do that, I must run jQuery functions only after it is really loaded.

I've tried two pure JS ways:

<script src="js/jquery-2.2.2.min.js" async></script>
<script>
    window.addEventListener('load', function() {
        //stuff
    }, true);
</script>

And

window.onload = function() {
    //stuff
}

But even so I still get Uncaught TypeError: $(...) is not a function at...

How do I fire jQuery functions after the lib is fully loaded?

Luiz
  • 2,429
  • 8
  • 28
  • 43
  • Please provide a [mcve] – charlietfl Mar 11 '17 at 13:33
  • You just need to add code after jquery library loaded (script tag) – Pranav C Balan Mar 11 '17 at 13:35
  • You get that error when jQuery **isn't** loaded at all. Load jQuery first, then as @PranavCBalan suggested add the rest afterwards.. Plus if you just wrap the functions in `$(document).ready(` you should 90% of the time be ok. – zer00ne Mar 11 '17 at 13:35
  • 1
    Yes. I cannot just put after the lib because I am loading the lib asynchronously in order to suit Google PageSpeed Insights requirements – Luiz Mar 11 '17 at 13:38
  • 2
    Possible duplicate of [Checking if jquery is loaded using Javascript](http://stackoverflow.com/questions/7341865/checking-if-jquery-is-loaded-using-javascript) – Keerthana Prabhakaran Mar 11 '17 at 13:38
  • Inject scripts like Google does. – zer00ne Mar 11 '17 at 13:44
  • Does this answer your question? [How to make script execution wait until jquery is loaded](https://stackoverflow.com/questions/7486309/how-to-make-script-execution-wait-until-jquery-is-loaded) – rogerdpack Mar 24 '20 at 04:49

5 Answers5

13

You need to add the script only after jQuery library is loaded using script tag.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
  // your code should be here
  alert(typeof jQuery)
</script>

The document ready handler is using to execute the code only after DOM elements are loaded.

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script>
  console.log('Outside document ready handler ' + $('.test').length)

  $(document).ready(function() {
    console.log('Inside document ready handler ' + $('.test').length)
  });
</script>
<div class="test"></div>

UPDATE 1: You can use defer if script is in a file, refer following question: jquery loaded async and ready function not working


UPDATE 2: Or you can bind load event handler to the script tag using addEventListener method.

<script async id="script" src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript">
  document.getElementById('script')
    .addEventListener('load', function() {
      alert(typeof jQuery)
    });
</script>

FYI : I don't know why you are doing this, for optimizing the speed of content load it's always better to move the script tags at the end of body which helps to load content first.

Community
  • 1
  • 1
Pranav C Balan
  • 113,687
  • 23
  • 165
  • 188
  • Thanks. But as described in the question, I must load jQuery asynchronously. – Luiz Mar 11 '17 at 13:40
  • Sure. Edited the post. – Luiz Mar 11 '17 at 13:46
  • 1
    @Luiz : http://stackoverflow.com/questions/37272020/jquery-loaded-async-and-ready-function-not-working – Pranav C Balan Mar 11 '17 at 13:50
  • Thanks for your time and help. – Luiz Mar 11 '17 at 13:53
  • In your second example you're using jquery to check for jquery. If '$' is not loaded, you aren't going to be able to run $(document).ready() – Scott May 14 '19 at 16:16
  • 1
    The "bind" solution was perfect for my usage case - running a piece of script from console to inject jQuery into a page, and then run jQuery-specific functions (once they were available). Thank you for the solution, @PranavCBalan – Luke Stevenson Feb 21 '22 at 00:29
9

You could do something like this:

function checkVariable(){
   if ( window.jQuery){
      Do your jquery stuff here
   }
   else{
      window.setTimeout("checkVariable();",100);
   }
}
checkVariable();

Apologies for the formatting...stuck on my phone right now.

Travis Acton
  • 4,292
  • 2
  • 18
  • 30
  • 2
    You need to change `windows.setTimeout` to `window.setTimeout` – Jlil Nov 09 '17 at 20:09
  • This worked perfectly in a particular project where I was only allowed to insert html, css, and javascript in the middle of the body (through PHP), but was not allowed to add more custom javascript at the end of the body, where jQuery and other js scripts were loaded. – alds Aug 11 '20 at 20:43
2

I did not see this method listed, so I thought I would demonstrate using the JavaScript HTML DOM EventListener.

Example #1 Using the jQuery.ready() Method:

<p id="test-jquery">jQuery Not Loaded</p>

<script>
  $(document).ready(function() {
    var elem = $('#test-jquery');
    elem.text('jQuery Is Loaded');
  });
</script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

This method will not work since jQuery has yet to be loaded. Running the above example will output:

ERROR: {
  "message": "ReferenceError: $ is not defined",
  "filename": "https://stacksnippets.net/js",
  "lineno": 13,
  "colno": 3
}

Example #2 Using the addEventListener() Method:

<p id="test-jquery">jQuery Not Loaded</p>

<script>
  window.addEventListener('DOMContentLoaded', function() {
    var elem = $('#test-jquery');
    elem.text('jQuery Is Loaded');
  });
</script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

This method will work since we are listening for the Window DOMContentLoaded event.

From Mozilla:

The original target for this event is the Document that has loaded. You can listen for this event on the Window interface to handle it in the capture or bubbling phases. For full details on this event please see the page on the Document: DOMContentLoaded event.

A different event, load, should be used only to detect a fully-loaded page. It is a common mistake to use load where DOMContentLoaded would be more appropriate.

Daerik
  • 4,167
  • 2
  • 20
  • 33
1

You can use this:

<script>
    document.addEventListener('readystatechange', event => {
        if (event.target.readyState === "complete") {
            // window loaded, external resources are loaded too...
            jQuery(function($) {
                // your code here: $("a").css(...)
            }
        }
    });
</script>

I used it when inline jQuery script did not work on safari (Mac and iOS) and this solved the problem.

David Najman
  • 487
  • 4
  • 7
0

Use document.ready or load the library in the header. That should work.. Be sure to load in the right folder or in the right link. If you are usying a link to load jquery then be sure to have an internet connection