When a browser loads an HTML page, it reads your HTML from top-to-bottom.
So ordering is important.
There are complexities of course. I'm not talking about deferred or asynchronous scripts here. But the top-to-bottom simplification helps us understand your problem.
Your script is inside test.js
, so it will be loaded and run before [body] is ready.
But test.js
has this line:
document.getElementById("add2").innerHTML = add(5,10,15,20);
This line is not inside a function, so the browser will try to run it immediately.
The call to add()
will work because it has been declared in the file. But document.getElementById("add2")
will not, because it is an instruction to access the following HTML in the [body]:
<p id="add2"></p>
But the [body] has not been "read" yet, so the JavaScript DOM API does not know about it.
However, you have partially solved the problem already using the onload
attribute of the [body] tag. You've just used the wrong function with it.
That onload
is an instruction to run a function after [body] has been completely read. So if you changed your document.getElementById
line to be inside a function:
function runWhenBodyHasLoaded () {
document.getElementById("add2").innerHTML = add(5,10,15,20);
}
And told the [body] tag to run the function after everything has loaded:
<body onload="runWhenBodyHasLoaded()">
Then <p id="add2"></p>
will be ready in time to access it with document.getElementById
.