reptile7's JavaScript blog
Thursday, May 18, 2006
 
The Randomizable If...else
Blog Entry #39

HTML Goodies' JavaScript Primers #23, "Producing Random Statements and Images," wraps up our tour of introductory applications of if...else statements. In accord with the primer title, the Primer #23 Script displays random statements, whereas the Primer #23 Assignment addresses the display of random images. A fairly simple strategy is at work in both situations: we'll use a modulo operation, discussed in Blog Entry #36, to generate a small set of random numbers, which are then associated, respectively, with an equal number of items - text strings or image files - via a series of if statements; once indexed in this manner, these items are then randomly written to the page by normal document.write( ) statements. In illustration, let's first look at the Primer #23 Script:

<html><body>
<script type="text/javascript">
var0="An Apple A Day";
var1="A Stitch in Time";
var2="Bird in the Hand";
now=new Date( );
num=(now.getSeconds( ))%3;
document.write("Random Number: " + num + "<br>");
if (num == 0) // if statement #1
{cliche=var0;}
if (num == 1) // if statement #2
{cliche=var1;}
if (num == 2) // if statement #3
{cliche=var2;}
document.write(cliche);
</script>
<p>....as I always say.
</body></html>

The now=new Date( ); num=(now.getSeconds( ))%3; code generates a random number num whose value is 0, 1, or 2, these being the possible remainders for divisions using 3 as the divisor.

Preceding the random number code are three statements that assign text strings, one for each random number value, to the variables var0, var1, and var2. These identifiers are not related to the var keyword used for declaring variables - more on this in a bit.

Following the random number code is first a document.write( ) command that displays the value of num (contra the primer, there's no need for this command to be all on one line - it's fine as it is originally) and then a series of if statements that connect the var0, var1, and var2 text strings to the values of num. Consider, for example, if statement #1:

if (num == 0) {cliche=var0;}

As you can deduce, this statement associates the "An Apple A Day" (var0) string with the 0 value of num, specifically saying, "If it's true that num and 0 are equal, then assign var0 and its value ['An Apple A Day'] to the variable cliche." Similarly, if statements #2 and #3 respectively associate the "A Stitch in Time" (var1) and "Bird in the Hand" (var2) strings with the 1 and 2 values of num.

If a given if statement's condition is true, then the conditions of the other two if statements are necessarily false and their {commands} will be ignored by the browser.

In sum, each if statement uses a specific value of num to assign a specific text string to cliche, which is written to the page by the document.write( ) command at the end of the script. Because num is a random number, then the script if statement (#1, #2, or #3) that executes is random and the displayed value of cliche is also random. Pretty straightforward.

Let's briefly get back to the var0, var1, and var2 variable names. In the "Deconstructing the Script" section of the primer, Joe says, "Notice that we DO NOT have the var num=num+1 in this one. It's not needed because we denoted our three variables starting with 0. If we started with 1, then we would need to." Joe is implying here that var0, var1, and var2 are indexed members of a var[i] variable array. (We'll take up the JavaScript Array object, and the variabilization thereof, in Primer #26.) Not so. A few comments in this regard:

• First, var itself is, not surprisingly, a JavaScript reserved word and is thus an unsuitable variable name; by extension, var[0], var[1], and var[2] (had Joe's syntax been correct, with square-bracketed index numbers) would also be unsuitable.

• It follows that the 0, 1, and 2 characters in var0, var1, and var2 are not index numbers at all, and thus var0, var1, and var2 are just ordinary variable names, no different from var3, var4, and var5 or from tom, dick, and harry for that matter.

• The real reason, then, we don't need a num=num+1 statement is that the conditions of if statements #1, #2, and #3 compare num with the numbers 0, 1, and 2. If we wanted to, we could add a num=num+1 statement and then compare num with the numbers 1, 2, and 3 (e.g., if (num == 1) {cliche=var0;} and so on), but this would of course be unnecessary.

As it appears in the primer, the Primer #23 Script works A-OK, and yet there's a sense of clutter here that rubs me the wrong way. Is it really necessary to variabilize the text strings? Do we really need to have two document.write( ) commands? Man, I just can't go any further until I rewrite this thing:

<script type="text/javascript">
now=new Date( ); num=(now.getSeconds( ))%3;
if (num == 0) cliche="An Apple A Day";
if (num == 1) cliche="A Stitch in Time";
if (num == 2) cliche="Bird in the Hand";
document.write("Random Number: " + num + "<br>" + cliche);
</script>
<p>....as I always say.

There. I feel much better now.

To reload or not to reload

"Having to reload the page to see different random numbers and quotes is somewhat of a pain."

I couldn't agree more. It'd be much more convenient if we could just click a button that renews the random number/statement in, say, a borderless text box, yes? Here's the code:

<script type="text/javascript">
function randtext( ) {
now=new Date( ); num=(now.getSeconds( ))%3;
if (num == 0) cliche="An Apple A Day";
if (num == 1) cliche="A Stitch in Time";
if (num == 2) cliche="Bird in the Hand";
document.f23.t23.value="Random Number: " + num + "; " + cliche; }
</script>
<form name="f23">
<input type="button" value="Click here to display a random number/statement below." onclick="randtext( );"><p>
<input name="t23" size="50" style="border:0px;">
</form>

Try it out (depending on your browser, more than one click may be necessary):


The Primer #23 Assignment

In the Primer #23 Assignment, Joe asks the reader to adapt the Primer #23 Script to the random display of images; he offers for the assignment three images - "pic1.gif", "pic2.gif", and "pic3.gif" - and provides two answer scripts, which are briefly discussed below.

(1) Assignment answer script #1: "Possible Answer 1 of 2"

Answer script #1 largely parallels the Primer #23 Script. Joe adds a num=num+1 statement to the random number code and then compares num to the numbers 1, 2, and 3 in the script's if statements (vide supra). The randomized image file is again assigned to cliche and the image is displayed via the following code:

quot="'"; // this is double quote, single quote, double quote which produces '
document.write("<img src=" + quot + cliche + quot +">");

For some strange reason, Joe chose to variabilize the single quotes that would ordinarily surround the src attribute value in the <img> tag; this is unnecessary, as these single quotes can be brought inside of the document.write( ) double quotes as follows:

document.write("<img src=' " + cliche + " '>");

(More sloppily, the single quotes here can also be omitted without causing any problems.)

(1) Assignment answer script #2: "Or if You are REALLY Clever"

Answer script #2 comes out of left field. Joe ditches the if statements altogether and instead applies the var1, var2, and var3 identifiers to randomizing the image file and displaying the image via the following command:

document.write("<img src=" + quot + eval("var"+num) + quot +">"); // quot="'";

Ah, our good friend the eval( ) function, which we briefly discussed in the previous post; once again, as in Primer #22, Joe says not a word here about eval( ) and what it does. So how does this command work? What's going on? It's pretty simple, actually. Suppose that num is 1. Concatenating the string "var" and the number 1 ("var"+num) gives the string "var1". (Netscape's "Data Type Conversion" documentation notes, "In expressions involving numeric and string values with the + operator, JavaScript converts numeric values to strings"; its "String Operators" documentation notes that the concatenation of two string values returns another string.) The string "var1" is then evaluated by the eval( ) function to give pic1.gif, which is assigned to the src attribute of the image placeholder as in the first answer script. (The strings "var2" and "var3" are similarly evaluated to pic2.gif and pic3.gif, respectively.)

Thus does the eval( ) function coordinate (a) the random number num, (b) the var# identifiers, which now do serve as an index, and (c) the pic#.gif image files. Clever indeed, but not something that a Weekend Silicon Warrior such as myself would come up with.

Now, perhaps you are thinking to yourself, "The use of the eval( ) function in the Primer #22 Script was redundant; what happens if we remove it here?" Good question. Again, suppose that num = 1. The command:

document.write("<img src=' " + "var"+num +" '>");

assigns the string "var1" to the image src attribute. With respect to the script, "var1", in contrast to "pic1.gif", is not an image file name. Result: no image loads, although no errors are thrown. FYI, the command:

document.write("<img src=' " + var+num +" '>");

throws a syntax error with both MSIE and Netscape.

However, what we can do is write the image with the following eval( )-less command:

document.write("<img src='pic" + num + ".gif'>");

Noteworthily, this command renders unnecessary the var#="pic#.gif" statements at the beginning of the script.

Finally, my I-don't-want-to-reload script above is easily retooled for displaying a random image. Try it out below:




....describes my mood today.
Click here for the code.

We will certainly encounter more uses of if...else statements in future scripts. Meanwhile, in the next two posts we'll switch gears and take up JavaScript looping techniques, beginning with a discussion of for loops in Primer #24.

reptile7

Comments: Post a Comment

<< Home

Powered by Blogger

Actually, reptile7's JavaScript blog is powered by Café La Llave. ;-)