...

View Full Version : question about the order script is written in



Redd4
11-15-2012, 12:32 AM
guys hey. im trying to learn javascript, and i have a question on something thats throwing me. it relates to the order in which its written. its probably very obvious and simple, but i cant see it.

in the code below, why is - window onload - at the bottom? i understand why the js links are at the bottom of a html page, but not why this seemingly reverse order is used in a .js file.
any and all advice appreciated, thanks for reading.




function preparePage() {
document.getElementById("mainContent").onclick = function() {
if ( document.getElementById("mainContent").className == "example") {
document.getElementById("mainContent").className = "";
} else {
document.getElementById("mainContent").className = "example";
}
};
}

window.onload = function() {
preparePage();
};

AndrewGSW
11-15-2012, 12:49 AM
In JavaScript the order of declarations is important, so functions should be defined before they are assigned to a variable or called. However, for your particular code-example, this requirement may be side-stepped because your call to preparePage() is within a closure, so you could switch the order and it should still work - try it. Good description here (http://stackoverflow.com/questions/3887408/javascript-function-declaration-and-evaluation-order).

Personally I don't often encounter an issue with this as I always (where possible) define my functions before I call them. It is also a custom, or tradition, to define functions before the assignment to 'window.onload'.

minder
11-15-2012, 02:37 AM
why is - window onload - at the bottom?

In this case the window.onload could be put anywhere in your script because all you are doing is assigning something to the browser window's onload event handler. That something (in this case an anonymous function) does not get executed until the browser triggers the window's onload event - ie. the page has finished loading completely, including downloading all the images and loading all the javascript. When the onload event is triggered, the event's handler (anonymous function) calls the preparePage() function and so preparePage() is executed after the window has finished loading.

If you did


window.onload = preparePage; //this is a valid js statement

then the function preparePage would have to be defined before the window.onload because in this case you are assigning a reference to a function and the function needs to be first defined before you can assign references to it to anything.

Old Pedant
11-15-2012, 05:16 AM
And *IF* you followed Felgall's suggestion for writing modern JavaScript, it is all a non-issue.

You could write the page thus:


<html>
<body>
<div id="mainContent"> ... </div>

<script type="text/javascript">
(
function( )
{

document.getElementById("mainContent").onclick =
function()
{
this.className = ( this.className == "example") ? "" : "example";
}
} /* end of anonymous master function */

)( ); /* self-invoke master function */
</script>
</body>
</html>


Notice that I also rewrote the onclick to be much simpler/more efficient. It could have been written that way in tho original.

Old Pedant
11-15-2012, 05:22 AM
If you did

window.onload = preparePage; //this is a valid js statement
then the function preparePage would have to be defined before the window.onload because in this case you are assigning a reference to a function and the function needs to be first defined before you can assign references to it to anything.

Hmmm...



<html>
<head>
<script type="text/javascript">
window.onload = doit;

function doit( )
{
document.body.style.backgroundColor = "lightblue";
}
</script>
</head>
<body>
REALLY?
<br/><br/>
Think again, Minder.

</body>
</html>


Functions do *NOT* have to be defined before you make a *REFERENCE* to them. JavaScript compiles all functions before it attempts actually USE the references.

Old Pedant
11-15-2012, 05:24 AM
And you can even do that ad nauseum:


<html>
<head>
<script type="text/javascript">
window.onload = doit;

function doit( )
{
setTimeout( doit2, 5000 );
}

function doit2( )
{
document.body.style.backgroundColor = "lightblue";
}
</script>
</head>
<body>
See? Just wait a few seconds...
<br/><br/>
JavaScript is more flexible than you think.
</body>
</html>

minder
11-15-2012, 07:01 AM
JavaScript compiles all functions before it attempts actually USE the references.

Then how come when I run this in FF16 on a xampp server I get an error in the error console in FF saying


referenceError: runMe is not defined
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title></title>
<script type="text/javascript">
window.onload=runMe;
</script>
</head>
<body>
<script type="text/javascript">
function runMe(){
alert('xxx');
}
</script>
</body>
</html>

Redd4
11-15-2012, 10:43 AM
guys thanks so much for helping me out. really appreciate your taking the time.

Philip M
11-15-2012, 11:25 AM
Then how come when I run this in FF16 on a xampp server I get an error in the error console in FF saying


<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<title></title>
<script type="text/javascript">
window.onload=runMe;
</script>
</head>
<body>
<script type="text/javascript">
function runMe(){
alert('xxx');
}
</script>
</body>
</html>





Because you have placed the call to runMe() in a separate script, and at the moment it is terminated by </script> that function does not yet exist.


<script type="text/javascript">
window.onload=runMe;
function runMe(){
alert('xxx');
}
</script>

works just fine. :)

minder
11-15-2012, 11:35 AM
Because you have placed the call to runMe() in a separate script, and at the moment it is terminated by </script> that function does not yet exist.


Correct answer.

So old pedant saying


JavaScript compiles all functions before it attempts actually USE the references. is not strictly true which my example proved.

So as per his code


REALLY? <br/><br/> Think again, Minder.
the same applies to him :)

Philip M
11-15-2012, 11:44 AM
Correct answer.

So old pedant saying

is not strictly true which my example proved.

So as per his code


REALLY? <br/><br/> Think again, Minder.
the same applies to him :)

Old Pedant was not pedantic enough!

Functions do *NOT* have to be defined before you make a *REFERENCE* to them. JavaScript compiles all functions within the same script before it attempts actually USE the references.

OK, bullant?

minder
11-15-2012, 11:51 AM
Old Pedant was not pedantic enough!


Agreed, as my example proved.

devnull69
11-15-2012, 11:53 AM
And additionally this won't work


window.onload = doit;

var doit = function() {
...
}

So function doit() is not equivalent to var doit = function()

Old Pedant
11-15-2012, 07:26 PM
And additionally this won't work


window.onload = doit;

var doit = function() {
...
}

So function doit() is not equivalent to var doit = function()

Correct. When you assign a function to a variable, the rules are different.

But why do any of this? Use "unobtrusive JavaScript" as I showed in post #4 then you don't NEED to make any forward references. You don't even need the onload code to be its own function.

It's cleaner, simpler, and list to Felgall: He has a host of other reasons to do it that way.

minder
11-15-2012, 07:34 PM
But why do any of this?

It comes down to personal preference of how you want to code. Me, my preference is to put all the js in the <head> section unless it must go elsewhere.

I can't be bothered scrolling down to the bottom of web pages looking for javascript and unless you have a huge amount of javascript then any potential gain in page loading time by putting your js at the bottom of the page won't be noticeable to the naked eye.

Old Pedant
11-15-2012, 09:50 PM
It's not a matter of performance gain. I agree with you on that issue: It would be the relatively rare page where it would make a noticeable difference.

I like Felgall's style because:
(1) It introduces NO global variables into the page, so you can't possibly conflict with any other scripts on the page.
(2) It almost always needs less total code to implement.

I wasn't sure I liked the style, at first, but I have swung completely around to Felgall's way of thinking. In almost all new coding I do I use that style.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum