-4

When i declare script tag in head tag my code doesn't work, example:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>Untitled Document</title>
  <script type="text/javascript" src="jquery-1.11.2.js" async></script>
  <script type="text/javascript" src="skript.js" async></script> 
</head>
<body> 
  <p>
    Click "Try it" to execute the displayDate() function.
  </p>
  <button id="myBtn">
    Try it
  </button>
  <p id="demo"></p>
</body>  
</html>

but when i set the script tag in the bottom body tag it works, example:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>Untitled Document</title>  
</head>
<body> 
  <p>
    Click "Try it" to execute the displayDate() function.
  </p>
  <button id="myBtn">
    Try it
  </button>
  <p id="demo"></p>
  <script type="text/javascript" src="jquery-1.11.2.js" async></script>
  <script type="text/javascript" src="skript.js" async></script> 
</body>  
</html>

skript file is containing the following:

document.getElementById("myBtn").onclick = function(){displayDate()};

function displayDate() {
    document.getElementById("demo").innerHTML = Date();
}

does anyone have a precise answer why is this happening?

Dusan
  • 755
  • 5
  • 16
  • BECAUSE you reference an element before it exists when it is in the head. – epascarello Jan 18 '15 at 21:36
  • http://learn.jquery.com/using-jquery-core/document-ready/ check this out for further explanation. – Craicerjack Jan 18 '15 at 21:39
  • So if I am referencing a tag in a script a script tag must be after the tag that is referenced in script? – Dusan Jan 18 '15 at 21:39
  • there are also solutions in vanilla JavaScript, a full library like jQuery is not the right answer for this "small" and general problem – Daniel Ruf Jan 18 '15 at 21:41
  • @DanielRuf I wasnt suggesting it as an answer but it does provide a little information about waiting for the dom to load before you can maipulate it. – Craicerjack Jan 18 '15 at 21:47
  • sure, let's take a look here https://github.com/jquery/jquery/blob/master/src/core/ready.js#L81 – Daniel Ruf Jan 18 '15 at 21:49

3 Answers3

1

Scripts should always be loaded at last and at the bottom of the body so they can access the DOM and the elements.

You can wrap this around your code, so it is executed when eversthing is loaded

document.addEventListener("DOMContentLoaded", function() {
  // your code
});

or

document.attachEvent("onreadystatechange", function(){
  if (document.readyState === "complete"){
    document.detachEvent( "onreadystatechange", arguments.callee );
    // your code
  }
});

see the official sourcecode of jQuery ready event here: https://github.com/jquery/jquery/blob/master/src/core/ready.js#L81

it calls the completed()-method, when the page is fully loaded

https://stackoverflow.com/a/21814964/753676 and How can I detect DOM ready and add a class without jQuery? give you the same answers

Community
  • 1
  • 1
Daniel Ruf
  • 6,949
  • 10
  • 55
  • 108
  • i'm curious is this often used in practice? How about this approach this is working also: document.getElementById("myBtn").addEventListener( "onclick", displayDate, false ); document.getElementById("myBtn").onclick = function(){displayDate()}; function displayDate() { document.getElementById("demo").innerHTML = Date(); } – Dusan Jan 18 '15 at 21:59
  • why isn't the event onclick added in the second statement in this example? – Dusan Jan 18 '15 at 22:01
  • because the second statement just works when the DOM and the element can be accessed. The first statement adds the event, when the element is available http://stackoverflow.com/questions/6348494/addeventlistener-vs-onclick – Daniel Ruf Jan 18 '15 at 22:11
0

Script is executing before DOM tree has been created. So if you add the script in the head, function is executing before the DOM tree has been created. If you want to add the script in the head, call function in window load.

edonbajrami
  • 2,106
  • 22
  • 34
0

You have to think the script tag as a content-inclusion tag. What you are doing in the first code is to include a content (the script) that needs data that comes after it's introduction.

More than that, you have to keep in mind that DOM (the programmatic representation of your HTML) takes some time to be formed, so you need for that to be completed. There are a couple of ways to wait as per the answers above.

Tasos Vogiatzoglou
  • 2,297
  • 10
  • 16