2

This is an example of click button to pop up an alert.

<script  type="text/javascript"
    src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js">
</script>

If the above part is put in head part, it works. If the above part is put like below, it does not work. enter image description here

This drives me crazy since in an open source code, the author said that if the script source is put at the end of html, the page will load faster. I spent a lot of time to figure out why the source code do not work and I found out that the reason in the position of the script src part.

However, when I test on http://jsfiddle.net/eSud7/3/ the position of the script is not important.

Could anybody please explain why?

I am using Google App Engine and tested on Firefox browser.

Additional info: I am using this free template. Please download and check the index.html, The author put all script source at the end of document and it works. Why???????

John
  • 3,888
  • 11
  • 46
  • 84
  • Scripts (except for async=true, which I will not talk about) are executed in order they are encountered. So yes, order between scripts matters. –  Jan 16 '13 at 06:44

5 Answers5

3

Yes its true that you should include your script at the bottom of the page, In your case you are calling jquery function even before core library has loaded. You will have to include your script after jquery library because functions are defined in the library and as the code executes these function has to be referenced

//At the bottom of the page
<script  type="text/javascript"
    src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js">
</script>

<script>

      $(document).ready("#button").click(function() {
      alert('button clicked');
});
  </script>

However, when I test on http://jsfiddle.net/eSud7/3/ the position of the script is not important.

Thats because you have selected to load jquery library on load(Look at the left hand side), so your library is included in the DOM on body load i.e. in your fiddle your giving position of library is redundant

Update on OP comments

<script>
    $(document).ready("#button").click(function() { //Included at the header, jquery object like $ and function like ready not declared yet !!!
      alert('button clicked');
    });
  </script>

AT the bottom of the page

//Contains all the jquery functions
    <script  type="text/javascript"
            src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js">
        </script>
Sibu
  • 4,609
  • 2
  • 26
  • 38
  • Please look at http://jsfiddle.net/eSud7/3/ where the script source is put after my code. And it DOES work. Why? – John Jan 16 '13 at 06:51
  • @John the author is correct, but you have to include the library first, as i have explained in my answer – Sibu Jan 16 '13 at 06:57
  • I dont get it. The author include everything at the end of the document and it works for his site. However, it does not work for me. – John Jan 16 '13 at 06:58
  • @John i have updated my answer, the thing is you need to load jquery functions after its core library has been loaded – Sibu Jan 16 '13 at 07:06
3

Fact is that, only html elements will be rendered quickly & shown to you before performing script operation, and it looks like page is loading faster,

also javascript is interpreted not compiled by design, so it will be executed line-by-line, so if you are asking for some jquery function and they are not interpreted already then browser will throw error, that's why we need to add jquery in first line.

try running

<html>
  <body>
    <p> HTML Element</p>

     <script>
      alert("Hello World");
    </script>

  </body>
</html>

vs

<html>
    <head>
        <script>
            alert("Hello World");
        </script>
    </head>
    <body>
        <p> HTML Element</p>
    </body>
</html>

OR have a look on this first

Script executed at top

and then

Script executed at last

it will clear your concept.

also for your reference please have a look on this

Community
  • 1
  • 1
Saurabh Bayani
  • 3,350
  • 2
  • 25
  • 44
  • you are absolutely wrong, position of script is essential in page speed, read this http://stackoverflow.com/questions/855077/does-putting-scripts-on-the-bottom-of-a-web-page-speed-up-page-load and http://developer.yahoo.com/performance/rules.html#js_bottom – Sibu Jan 16 '13 at 07:31
  • 1
    I think you misunderstood me, i am saying that putting script at end just create illusion that page is loaded faster, because html elements are rendered & displayed as soon as page is opened. and of-course it is good practice "in some situation" to do same, like when you are going to do heavy operation in your elements, but imagine a situation where you are arranging DOM by script. in that situation all elements will be shattered on the page until script loads, and create bad User experience. please inform me if my answer is projecting something diffrent – Saurabh Bayani Jan 16 '13 at 07:42
2

Absolutely your script won't work because that don't get the required functions of the jquery.

So you have to use the script just below this script:

<script  type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js">
</script>

<script  type="text/javascript">
  // all your code stuff
</script>

This is the order you have to follow, it really doesn't matter to put your code at anywhere in you page then.

Jai
  • 74,255
  • 12
  • 74
  • 103
  • Please look at http://jsfiddle.net/eSud7/3/ where the script source is put after my code. And it DOES work. Why? – John Jan 16 '13 at 06:50
  • Well in your fiddle you have selected the jquery from the left side menu if you select the `no-wrap(head)` and remove the api reference that will be fired too. – Jai Jan 16 '13 at 07:10
  • Although you have not correctly coded the `doc ready` handler. – Jai Jan 16 '13 at 07:10
1

Scripts are executed in order they are encountered in the DOM1

So yes, order between scripts matters.

In this case, your script runs before jQuery does, so attempting to access $ results in a ReferenceError. To "fix" it, put your script under the jQuery script element. It doesn't matter if the scripts are in <head> or at the bottom of the <body>: but the relative order of the scripts is important.

Here is a trivial mockup of the invalid ordering:

<script>
   alert($)  // attempt to use $, but ..
</script>
<script>
   $ = "foo" // .. $ not set UNTIL here (later)
</script>

If these the order of two script elements were reversed then "foo" would be alerted, as expected.


1 (Except, perhaps, for those marked as async=true, which I will not talk about.)

  • Please look at http://jsfiddle.net/eSud7/3/ where the script source is put after my code. And it DOES work. Why? – John Jan 16 '13 at 06:51
  • @John jsfiddle.net *already loads jQuery (or another library) by default*. Select "No Library (Pure JS)" from the drop-down on the left. –  Jan 16 '13 at 06:52
  • oh my god!!! But this is what the author wrote his source code – John Jan 16 '13 at 06:53
  • @John I *don't care* what the author wrote. **I explained 1) The issue, and; 2) Why "it works" in jsfiddle.net**. Please take at least as much time to read and reflect on the explanations as I have taken to write them. –  Jan 16 '13 at 06:54
0

This answer is for those who are in the mystery why sometimes the code works and sometimes it does not when placing the library source at the bottom of the page.

After being in this mystery myself for quite a while, I featured it. There are 2 separate and distinct concerns in this matter, one is about executing the code and one is about loading the code.

The placement of jquery source does not matter as long as you are not executing any code when loading the page. Yes, you read that right and it absolutely correct.

Please allow me to elaborate with an example;

<script>
    $("#emailInput").change(function(){
        // perform some operations when a change is detected in the input emailInput
    });
</script>

<script src="https://code.jquery.com/jquery-3.5.0.min.js"></script>

The code above will be executed when the page is loaded. As you can see $("#emailInput"), having the jquery selector, is executed before the jquery library has been loaded and executed (this is where jquery will define $ and all the things it does). This is what causes the error Uncaught ReferenceError: $ is not defined to be thrown.

However, if the code is not executed when the page is loaded, we will not have any errors, this is also best explained with an example.

<html>
    <head>
        <script>
            function writeMessage(){
                $("#message").html("Surprise ladies!");
            }
        </script>
    </head>
    <body>
        <button onclick="writeMessage()">Click me</button>

        <div id="message"></div>

        <script src="https://code.jquery.com/jquery-3.5.0.min.js"></script>
    </body>
</html>

The code above is complete and correct, so you can try it to see it for yourself and it works absolutely fine. This is because the function writeMessage() has not been executed when the page was loaded. The function is executed only when the button is pressed; which is after the page has been loaded (by that time the jquery library has already been loaded and executed).

I have seen in the comments, in this link the code is working when the library is loaded after. Remove the jquery src found at the bottom, run it again and the jquery still works! My best guess would be, the code is using the library which is available on jsfiddle's website.

I hope this clarifies the mystery we all have been living in.

atish.s
  • 1,534
  • 11
  • 19