62

I was getting a problem .

<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <script type="text/javascript">
  alert(document.getElementsByTagName("li").length); 
  </script>
  <title>purchase list</title>
</head>
<body>
  <h1>What to buy</h1>
  <ul id="purchases">
    <li> beans</li>
    <li>Cheese</li>
  </ul>
</body>

When I put scripts in head, the result shows 0

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
                      "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en"> 
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <title>Shopping list</title>
</head>
<body>
  <h1>What to buy</h1>

  <ul id="purchases">
    <li>Cheese</li> 
    <li>Milk</li>
    <script type="text/javascript">
    alert(document.getElementsByTagName("li").length);
    </script>
  </ul>
</body>

When I tried to put scripts in body, the result shows 2. why there is such a difference? what is the main difference?

gustavohenke
  • 40,997
  • 14
  • 121
  • 129
Deepika C P
  • 1,263
  • 2
  • 13
  • 23
  • Because at the time of you calling it in the head, the `li` doesn't yet exist (As far as the DOM is concerned) – George Jun 14 '13 at 10:32
  • 1
    It is recommend to put all your JavaScript (not libraries but working JS that page uses) on bottom of page. As for libraries you should "include" them in ``.Note that, browser is rendering code from top to bottom. – Kyslik Jun 14 '13 at 10:34
  • 2
    possible duplicate of [Javascript - head, body or jQuery?](http://stackoverflow.com/questions/10994335/javascript-head-body-or-jquery) – James Donnelly Jun 14 '13 at 10:36
  • Very good explanation and recommendation: http://stackoverflow.com/a/24070373/548473 – Grigory Kislin Dec 18 '16 at 21:03

10 Answers10

28

What's the difference between putting script in head and body?

The time that it runs.

When I put scripts in head, the result shows 0 Shopping list

The elements you are trying to access don't exist when the script runs (since they appear after the script in the document).

Note that you can write a script so that a function is called later (for various values of later including "when the entire document has loaded") using event handlers.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
  • Can you explain why can I get e.g., innerHTML of a element with a script from the head, but the script from question cannot get the lenght. Thank you! – Boy Mar 27 '15 at 10:01
  • @Borna — See the last paragraph of the answer. – Quentin Mar 27 '15 at 10:05
  • 2
    I don't really see an answer there... I understand what can I achieve with event handlers, but thats not what I'm asking you. I want to know why script from the head can process element.innerHTML but the element.lenght cannot. It's just I got confused because you said elements doesn't exist if trying to access it from a script above those elements (head tag in our case). Please try to understand me, thank you. – Boy Mar 27 '15 at 10:26
  • Because it matters when the line of code is executed, not when it is declared. If it is in a function that runs late, it is fine. – Quentin Mar 27 '15 at 11:04
16

It's simple, JavaScript will go from up-down, unless you tell it to do something else. By the time it reaches the li elements, the JavaScript code has already been completed.

If you want to keep it in the head however, you could use the document.ready function and it will load only after the HTML it's loaded.

Rinon
  • 579
  • 5
  • 14
11

Head will get rendered before Body. If you're trying to access your li tags in the head, the obvious answer is that they are not created until the browser renders the body section and therefore cannot be referenced.

Darren
  • 68,902
  • 24
  • 138
  • 144
6

When scripts are included in the head they load or run before the content of the page. When you include them in the body they load or run after the preceding html. It's usually good practice to put scripts as close to the end of the body as possible.

br3w5
  • 4,403
  • 5
  • 33
  • 42
6

Because at the time of you calling it in the head, the li doesn't yet exist (As far as the DOM is concerned) – F4r-20 1 min ago

This is correct. But, try this:

<head>
      <meta http-equiv="content-type" content="text/html; charset=utf-8" />
      <script type="text/javascript">
        window.onload = function(){ alert(document.getElementsByTagName("li").length); }
      </script>
      <title>purchase list</title>
    </head>
    
    <body>
      <h1>What to buy</h1>
      <ul id="purchases">
        <li> beans</li>
        <li>Cheese</li>
      </ul>
    </body>
kiddorails
  • 12,961
  • 2
  • 32
  • 41
CastenettoA
  • 673
  • 5
  • 17
4

Generally scripts and CSS files must be fit into head, as good practice.

For more details about when to put in head and body tag, refer this link - Where should I put the CSS and Javascript code in an HTML webpage? & Should I write script in the body or the head of the html?

Community
  • 1
  • 1
Viraj
  • 179
  • 12
  • The top answers in the two linked questions do not actually support the assertion that putting the scripts in the head is "good practice". – yoniLavi May 30 '23 at 01:01
3

When you call:

alert(document.getElementsByTagName("li").length); 

You want to get an element that does not exist yet. because the head is the first thing that runs when you load the page.

it's searching for the li element, but it isn't yet there when the head loads.

You have to put it in the body because then, the list items exist. then it works.

Kees Sonnema
  • 5,759
  • 6
  • 51
  • 106
1

If you put script in head, javascript code gets executed even before controls in body tags are rendered. So if you want to keep your scripts in head tag, make sure they are executed once onload is completed. Below is an example:

 <script type="text/javascript">
function MyFunction() {
    alert(document.getElementsByTagName("li").length);
}
window.onload = MyFunction;
</script>
Nitin Agrawal
  • 1,341
  • 1
  • 10
  • 19
1

HTML document executes in Top-Down Approach.

  • In your case when you execute your HTML Document, it will execute head first. and as you can see, you wrote a script tag inside the head.

  • so, here a script tag will execute first. inside a script tag what you are going to do, you are finding the length of li tag which is available inside the body tag.

  • but at this moment, the browser doesn't execute the body tag yet.

  • so, your script will get 0 as the result.

    alert(document.getElementsByTagName("li").length);
Vishw Kadu
  • 11
  • 2
0

Following code executes the script in the head tag. Once without JQuery and then with JQuery that instructs the alert to display when the document is loaded $(document).reaady()

<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <script src="jquery-3.5.1.min.js"></script>
    <script type="text/javascript">
      // First alert will show # of opttions as 0, because the document is not ready yet
      alert(document.getElementsByTagName("li").length);
      // First alert will show the correct # of opttions as 2
      $(document).ready(function () {
        alert(document.getElementsByTagName("li").length);
      });
    </script>

    <title>purchase list</title>
  </head>
  <body>
    <h1>What to buy</h1>
    <ul id="purchases">
      <li>beans</li>
      <li>Cheese</li>
    </ul>
  </body>
Aber Abou-Rahma
  • 174
  • 1
  • 9