Body script invoking before onload script?

Trying to re-invent myself. New to my laptop, Windows 8, Javascript and HTML5. The symptom is the sequence and content of the alert messages:

(line39): body script
(alert line 21):GetNextCard
(line 25): deck[24] = undefined
24, undefined, 51
(line 41):next card isundefined
(alert line 17): deck[18] = 5d
then the "1c.gif (ace of clubs) does appear on the canvas (see last line before </body> below)

It appears that the body script invoking the GetNextCard() function is running before the <body "onLoad=“Deal()”>

Any ideas?

I also suspect that I may be having scope issues with my deck array. My readings suggest Javascript treats “this.” differently than, say, php – but I can’t get my arms around how that might affect me here.

Appreciate your thoughts.


Here’s the code

<!DOCTYPE html>
<title>Simple Solitare</title>
<meta name="" content="">
<script type="text/javascript">
	deck=new Array(53);
	cardsLeft = 52;
	function Deal(){
			deck[i] = i+"c";
			deck[i+13] = i+"d";
			deck[i+26] = i+"h";
			deck[i+39] = i+"s";
		} // end for
		cardsLeft = 52;
		alert("(alert line 17): deck[18] = " + deck[18]);
	} // end function Deal

	function GetNextCard() {
		alert("(alert line 21): GetNextCard");
		if(cardsLeft < 1) return false;
		// get a number between 1 and the number of remaining cards
		i = Math.floor(Math.random() * cardsLeft) + 1;
		alert("(line 25): deck["+ i +"] = "+ deck[i]);
		var nextCard = deck[i];			// pull that card
		deck[i] = deck[cardsLeft];      // replace that card with the last in the deck
		if (cardsLeft >45) alert (i +", " + nextCard + ", " + cardsLeft);
		return nextCard;
	} // end function GetNextCard

<body onload="Deal()">
<canvas id="board" width="800px" height="600px"></canvas>
<script type="text/javascript">
alert("(line 39): body script");
var nextCard = GetNextCard();
alert("(line 41): next card is" + nextCard);
<p> <img src="1c.gif"/> </p>

All JavaScript should be placed just before the </body> tag. When placed higher in the page than that either some of the elements of the page it wants to interact with may not have loaded yet or you need to delay running it until after all the images and other files attached to the page finish loading as well. Attaching it all just before the </body> tag allows the code to run at the soonest point without needing to jumble it with the HTML and without needing to examine all the code to see what parts of the page it needs to reference.

I know of exactly three scripts that are the exceptions to this rule. One that potentially redirects to another page - that must go in the head so that the redirect can happen before any of the current page displays. The second updates classes on the <html> tag to change the CSS used to display the page when JavaScript is enabled - which should also go in the head of the page so it applys the correct styles. The third substitutes a local image for any remote images that fail to load and is the only situation where onload needs to be used.

Of course you can put scripts higher in the page and use onload but then your scripts need more code to handle that they are being called from the wrong place.

By taking the Deal() function call out of the <body onload> and assigning it as

<canvas id="board" width="800px" height="600px"></canvas>
<script type="text/javascript">
var DealObj = Deal();

I got the result I was looking for.

Still… I’d like to know why the body-script runs before the onload clause of the body element.

Felgall: We must have posted at the same time. Guess that happens. Your response answers my question about the “why”. Thank you