2

From what I have read the preferred format for javascript is in a separate file that is included at the end of the header. I have written a simple screen that increments indx on a time interval and reverses if the Previous button is pressed. If I include the script at the end of the body it works fine, but if I include at the end of the header the buttons have no effect. Am I missing something here? Could someone explain please?

var buttons = document.getElementsByTagName("button");
for (var i = 0; i < buttons.length; i++) {
buttons[i].onclick = handleButtonPress;
}

var del = 5000;  /* time delay in milli seconds */
var indx = 0;
var direct = 1;
var intervalID = window.setInterval(proceed, del);

function proceed() {
 indx += direct;
 if (indx <= 0){
 indx = 0;
 direct = direct * -1;
 };
 msg = 'indx = ' + indx + ' direct = ' + direct;
 document.getElementById("msg").innerHTML = msg;
}

function test() {
 alert('this is a test')
}

function handleButtonPress(e) {
if (e.target.id == "next") {
direct = 1;
}
else if (e.target.id == "prev") {
direct = -1
}
}

function displayMsg(msg) {
document.getElementById("msg").innerHTML = msg;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Example Timeout + Buttons</title>

<!-- <script src="test.js"></script> Does not work here!! -->

</head>
<body>
<p id='msg'></p>
<p>
At start<br>
<button id="next">Next</button>
<button id="prev">Previous</button>
</p>

<!-- Script works here!! -->
<script src="test.js"></script>

</body>
</html>
Mick Sulley
  • 99
  • 2
  • 11
  • Modern preference is to put scripts as close to the `

    ` closing tag as possible. Your script fails when it's in the head because the DOM hasn't been built at the time it runs, so it can't find any `

    – Pointy Dec 10 '15 at 22:49
  • A javascript file runs over your file as soon as you include it. This means it won't see your divs if you put it on top :) – Vince Verhoeven Dec 10 '15 at 22:50

3 Answers3

3

This is not a problem, but a consequence of trying to use or reference DOM elements before they ever exists:

  • When loading your js at the bottom of the HTML:
    • the DOM is already loaded
    • you can manipulate it at will.
  • When loading your js into the HEAD:
    • the DOM is not already loaded
    • you have to make the page execute the javascript only after the body has already loaded:
    • With jQuery's $()
    • With the onload event of the BODY DOM element.
Nicolás Ozimica
  • 9,481
  • 5
  • 38
  • 51
2

It is ok to have the js src there, the only problem is that the javascript will be loaded after. To make sure we can use the Javascript only after it's completely loaded, you can add this in the Javascript:

document.addEventListener("DOMContentLoaded", function(event) { 
    //do work
});

or in the body tag, you can add scripts from this answer :javascript - $(document).ready equivalent without jQuery - Stack Overflow

Community
  • 1
  • 1
FlipFloop
  • 1,233
  • 1
  • 14
  • 25
1

Include the script at the bottom. This is the right way to do it.

As your script manipulates the DOM, the DOM must be rendered before it works.

Another positive side effect is that your page will get loaded in the browser and present the content before all scripts are loaded. When working with large libraries this is very good!

Bjørn Sørensen
  • 901
  • 1
  • 6
  • 14