21

I have a project where all the JS files are referenced in the footer, as is recommended for speed of page loading, including the link to the Jquery file. This code produces an "Uncaught ReferenceError", I assume because Jquery has not been defined before my script is called:

<html>
    <head>
        <link rel="stylesheet" type="text/css" href="css/bootstrap.css">
    </head>
    <body>
        <p>
            <a href="#" data-toggle="popover" title="first popover" id="example">hover over me</a>
        </p>
        <script type="text/javascript"> 
            $(function(){
                $('#example').popover({ trigger:'hover' });
            })
        </script>

        <script type="text/javascript" src="js/jquery.min.js"></script>
        <script type="text/javascript" src="js/bootstrap.js"></script>
    </body>
</html>

If I move the Jquery link to the header, then the code runs fine, but this will slow the page loading time.

Is there a better way to declare my function so that it does not throw this UncaughtReference error, or is keeping the Jquery link in the head the best solution?

Lukasz Koziara
  • 4,274
  • 5
  • 32
  • 43
Ila
  • 3,528
  • 8
  • 48
  • 76
  • 3
    You have to load the script before you start writing code relying on said script. – tymeJV Apr 17 '13 at 15:22
  • 1
    Possible duplicate of [Uncaught ReferenceError: $ is not defined?](https://stackoverflow.com/questions/2075337/uncaught-referenceerror-is-not-defined) – Moradnejad Jun 18 '19 at 10:58

5 Answers5

17

It is because you are trying to use jQuery before jQuery has been loaded. You need to put libs like jQuery in the head of your document

<head>
    <link rel="stylesheet" type="text/css" href="css/bootstrap.css" />
    <script type="text/javascript" src="js/jquery.min.js"></script>
    <script type="text/javascript" src="js/bootstrap.js"></script>
</head>

Generally your scripts go at the end of the document near the close body tag and libraries such as the ones you are using go at the <head>

brenjt
  • 15,997
  • 13
  • 77
  • 118
  • 3
    Not necessarily in the `head`; just before any of the other JavaScript that relies on jQuery. – bdesham Apr 17 '13 at 15:23
  • Thanks, this answers the question I was asking: that in this case, as the scripts will be contained inside the document body, and I can't move them, the best place to call JQuery is in the head. – Ila Apr 17 '13 at 15:42
14

I like keeping jquery at the bottom, you'll just need to make sure the entire DOM is loaded first, and to check that without jQuery as that's not usable yet. Try using this instead:

document.addEventListener("DOMContentLoaded", function(event) { 
      $(function(){
          $('#example').popover({ trigger:'hover' });
      });
});
cpres
  • 953
  • 1
  • 10
  • 13
7

You need to include jQuery before referencing the jQuery library.

Change to this:

<script type="text/javascript" src="js/jquery.min.js"></script>
<script type="text/javascript" src="js/bootstrap.js"></script>

<script type="text/javascript"> 
$(function(){
   $('#example').popover({ trigger:'hover' });
});
</script>

Also note that it is a good idea to include jQuery and other JavaScript in the footer of your document to ensure that page rendering is not delayed.

kyle.stearns
  • 2,326
  • 21
  • 30
  • 1
    OK. Because of project limitations (application generated code) the DOM position of the script content is non-negotiable, so I will have to put the JQuery in the header I guess. – Ila Apr 17 '13 at 15:24
  • @Ali: Not necessarily, check my answer. – Elliot Bonneville Apr 17 '13 at 15:25
4

Recently on jsTree site I've seen another technique

at the top (in the HEAD tag) you set just this:

<script>window.$q=[];window.$=window.jQuery=function(a){window.$q.push(a);};</script>

Now you can do <script>$(function () { /* your $() calls here */ });</script> whenever and wherever you want...

at the end include jquery.js as usal and then the last script is:

<script>$.each($q,function(i,f){$(f)});$q=null;</script>

hope this is usefull to someone...

Badjem79
  • 151
  • 1
  • 4
0

Scripts get executed from the top to bottom of the document in order, so You are trying to reference the the jQuery library before it is loaded.

To solve this, you can either put your own scripts in a separate file and import them after the jQuery library or put your script tag below the jQuery import.

hichris123
  • 10,145
  • 15
  • 56
  • 70
cfs
  • 10,610
  • 3
  • 30
  • 43