So far you are only able to write static pages. That is, they are set by the designer and may not be changed at run-time. Now we want to develop active/customized pages. These will allow us to have actions occur based on movements of the user and allow us to customize web pages with information tailored for the particular user. Code for JavaScript is written in a script as below:
<SCRIPT LANGUAGE="JavaScript"> <!-- Beginning of JavaScript - var name = "Josephine"; document.write("Good morning, "+name+"! "); if (name.length <= 4) document.write("Boy, you have a short name!"); else document.write("You have a pretty long name!"); printit(name); printit("Kim); // - End of JavaScript - --> </SCRIPT>
The script tag indicates the beginning of an executable program. The LANGUAGE attribure specifies the language used. The <!--
on the next line is treated as the beginning of a comment by browsers that cannot execute a script in the indicated language, and hence all text between that and -->
is ignored by those browsers. Otherwise the browser executes the code between <SCRIPT LANGUAGE="JavaScript">
and </SCRIPT>
.
This particular script defines a variable name
, which is initialized to "Josephine". The code document.write(...)
inserts the text inside the parentheses directly onto the web page. In this case, it inserts the string formed by concatenating (gluing together) the string "Good morning, ", the value of the variable name
and the "!".
The next statement is a more complicated statement which first examines the length of the value in variable name
(written as name.length
). If its length is less than or equal to 4, it prints a message about the user having a short name.
Otherwise it inserts text into the document remarking on how long the name is.
If //
occurs in a line then everything to the right of //
in the line is ignored. Similarly everything between "/* and "*/" is also ignored as a comment (no matter how many lines are between the symbols).
The document.write("...");
statement takes the string inside the parentheses and puts it on the web page. Thus if the length of name is less than or equal to 4, it writes "Boy, you have a short name!", otherwise you get the other message. Java lets you "glue" strings together (technically, its called concatenating strings) by using the "+" sign between strings. Thus in the statement document.write("Good morning, "+name+"! ");
, three strings are glued together. They are "Good morning, "
, the string kept in the variable name
, and "! "
. Notice that the variable name is not surrounded by double quotes. That is because we don't want the word "name" to be printed, we want the value it contains (in this case, "Josephine") to be printed.
We'll come back to the two printit
statements a bit later.
See if you can tell what this script is doing by reading it. Follow this link to see what happens when it is executed.
If you look at the source of that page, you'll see that I snuck in something extra, a function definition in the header. It looks like this:
<SCRIPT LANGUAGE="JavaScript"> <!-- Beginning of JavaScript - function printit(aName) { document.write(aName+", did you know this was written by the function, printit!<P>"); } // - End of JavaScript - --> </SCRIPT>(From now on, I won't bother to write the SCRIPT tags with JavaScript code.) A function groups together some code that can be executed anywhere in the program. In this case it contains the
document.write
statement that adds some stuff
to the page. In the first script I showed you, the next to last line was printit(name);
. When that was executed, it called the function printit, passing to it the string stored in name ("Josephine). When the function executed, it matched up name
in the call with the formal parameter aName
in the parentheses after function printit
. This is the way information is passed from a statement using the function to the actual code of the function (the stuff inside {}
). Thus the last line of the program was printit("Kim");
, which printed out the same text, except that aName
is now replaced by the string "Kim".
All functions written in JavaScript have the general form
function printit(params) { // lines of code (e.g. document.write(...), if ... then ... else, etc.) }where params is replaced by a list of names for information to be provided to the function and the "..." is replaced by any number of lines of JavaScript code. You can use the function by writing down its name followed by the correct number of parameters enclosed in parentheses. For example, the function
function matchnames(name1,name2) { // code omitted }could be called with
matchnames("Fred","Joan")
.
name
a good morning. Look at the code at the beginning for a guide as to what to change.
The following examples use a function called setTimeout to produce nice effects.
The built-in function setTimeout(code,delay)
executes code
after waiting delay
milliseconds.
First we have some relatively simple code to make animated pictures. We'll use the pictures of the same guy as was used yesterday in making animated gifs. Take a look at the page with him jumping! Be sure to stay there long enough to let all the pictures load.
Here is the page generating the pictures:
<HTML><HEAD> <TITLE>Animated Jumper</TITLE> <SCRIPT LANGUAGE="JavaScript"> <!-- Beginning of JavaScript - var current = 0; var imgCnt = 24; function cycle(){ current++; if (current == imgCnt){ current = 0;} document.banner.src="guy/guy"+current+".gif"; setTimeout("cycle()",500); } // - End of JavaScript - --> </SCRIPT> </HEAD> <BODY BGCOLOR="#FFFFFF" onLoad="cycle()"> <CENTER><IMG SRC="guy/jumper0.gif" NAME="banner" WIDTH="50" HEIGHT="100" ALT="jumper pictures"> <H2>We can make animations with JavaScript!</H2> </CENTER> </BODY> </HTML>The body of the page is pretty simple. It displays the image in "guy/jumper0.gif" in a field with name "banner" which is 50 x 100 pixels, and includes a header underneath. When the page is loaded, it calls the function
cycle()
(we'll discuss how that happens when we discuss events).
In the header,
the variables current
and imgCnt
keep track of the current image being displayed (starting with 0) and the total number of images. The images being displayed go from guy0.gif
to guy23.gif
, and are kept in a subdirectory called guy
. The function cycle
increases the variable current
by 1 (unless it has gone up to 24, in which case it resets it to 0). It then builds the file name for the current gif by concatenating the number to "guy/guy" and "gif". Thus when current
is 7, it creates "guy/guy7.gif". That file name is then stuck in the src field of the IMG field. Thus it changes the picture in the image field to the new picture. As this field holds successive images from these files, we get an animation of the guy jumping.
Here is a pretty cool example which shows how you can make a scrolling message at the bottom of your web page. Look at the code by selecting "Page source" under the View menu to see the code. The function scrollMsg()
is called when the page is loaded. The following code is included in the header:
var theMessage="Don\'t you think this scrolling message looks pretty cool!"+ " "; var msgLength=theMessage.length // the length of theMessage var startIndex=0; // where the string should begin function scrollMsg(){ var front = theMessage.substring(startIndex,msgLength); var rear = theMessage.substring(0,startIndex); self.status = front+rear; if (startIndex < msgLength){ startIndex++; } else { startIndex=0; } setTimeout("scrollMsg();",50); // Wait 50 milliseconds before calling scrollMsg() again. }The expression
theMessage.substring(start, length)
extracts the part of theMessage
starting from the character at position start
(where the first character is at position 0) and takes the next length
characters (if there are that many, otherwise just take from start
to the end). Thus front
ends up with all of the characters after the character at position startIndex
, while rear
gets the first startIndex
characters of theMessage
.
The statement startIndex++
increases the value of startIndex
by 1. Thus the if...then...else
statement increases the value of startIndex
by 1 if it is less than msgLength
and otherwise resets it to 0.
The built-in function setTimeout(code,delay)
executes code
after waiting delay
milliseconds. Thus in the above program, every 50 milliseconds, the program puts a slightly different message. Successive calls write a message which begins one character to the right of the previous message.
<HTML><HEAD> <TITLE>Script with Prompt</TITLE> <SCRIPT LANGUAGE="JavaScript"> <!-- Beginning of JavaScript - var name = prompt("Please enter your name!","Name"); // - End of JavaScript - --> </SCRIPT> </HEAD> <BODY BGCOLOR="#FFFFFF"> <SCRIPT LANGUAGE="JavaScript"> <!-- Beginning of JavaScript - document.write("Good morning, <EM>"+name+"!</EM>"); if (name.length <= 4) document.write("Boy, you have a short name!"); else document.write("You have a pretty long name!"); // - End of JavaScript - --> </SCRIPT> <P> Please click on the go-away box in the upper left hand corner when done. </BODY> </HTML>The only difference between this code and the earlier code is the script in the HEAD which creates a variable
name
, which gets the results of a call of prompt
. The built-in function, prompt
, takes two arguments and pops up a window. The window displays a string which is the first argument to prompt
. In this case the window would contain the string "Please enter your name". The window also has a slot for the user to write in. Initially the slot has written in it the value of the second parameter (in our case "Name", but we could have just as easily started it as empty by making the second parameter "", for an empty string). The function prompt
returns the value typed in the new window. Because prompt
is used in an assignment to name
, the string typed in is stored in name
(which is used later in the second script). Any script in a header is executed before text from the body can be executed or laid out on the page.
Aren't you impressed that we can customize the page with your name! Visit a page which contains this code to see how it works.
<FORM> Name: <INPUT NAME="name" TYPE=Text VALUE="Your name" SIZE="25" MAXLENGTH="25"> <!-- first input field --> <P> Age: <SELECT NAME="age" > <!-- a pop-up menu --> <OPTION>12 <OPTION SELECTED>13 <!-- this is the default choice --> <OPTION>14 <OPTION>15 <OPTION>16 <OPTION>17 </SELECT> <P> <INPUT NAME="cbLike" TYPE=Checkbox VALUE="yes" CHECKED> Check this box if you like this course. <!-- check box--> <P> <input type=button onclick="act(this.form);" value="Our reaction to your evaluation!"> <!-- a button which calls the function act --> <P> <INPUT TYPE=Reset VALUE="Reset form"> <!-- a button to reset the form to defaults --> </FORM>The
FORM
tags bound the form. Inside the form there are different INPUT
objects. The types include TEXT
(input fields), SELECT
(pop-up menus), CHECKBOX
(boxes that can be checked), BUTTON
(buttons), and RESET
(buttons to reset form to default values). Most of these input items have a NAME
field with a string value so that we can refer to them in a script. This particular form has a text field with name "name", a select field with name "age", a checkbox with name "cbLike", a button with no name, and a reset button with no name.
The VALUE
field of a input item is the string originally in the field, while for a button it is the label of the button. Select items need to be supplied with a list of options, which correspond to the values available on the pop-up menu. The options are headed by OPTION
tags. Notice that the default value (the one shown before the user makes a choice) is marked with a SELECT
attribute.
When a button is pushed, it generates an onClick
event. For now just notice that the value of the ONCLICK
attribute of the button above causes the code act(this.form)
to be executed. We'll look at the function act
when we study events in the next section. For now take a look at the form generated by this code.
Before we move into the next section, take a look at this fancy form which takes input from the user and makes a calculation. Feel free to look at the source code, but we'll take about the associated functions in the next section.
howOld
.
<FORM> <INPUT NAME="Forbidden" TYPE=Button VALUE="Don't touch me!" onClick="alert('I warned you once! Don\'t do that again!')"> <P> <INPUT NAME="DataField" TYPE=Text VALUE="Enter a number here" SIZE="20" MAXLENGTH="25" onChange="alert('Thanks for changing me to '+this.value+'!');"> <P> Enter an expression: <INPUT TYPE="text" NAME="expr" SIZE=15 > <INPUT TYPE="button" VALUE="Calculate" onClick="compute(this.form)"> <BR> Result: <INPUT TYPE="text" NAME="result" SIZE=15 > </FORM>
This example uses the onClick
and onChange
events. Not surprisingly, onClick
is triggered by clicking on a button, while onChange
is triggered by changing the value of a field (and selecting something else in the form). When an event is triggered for which there is an event handler, the code in that event handler is executed. Thus when the user clicks on the first button, the code associated with onClick
is executed, resulting in an alert dialog containing a warning. When something is changed in the text field, the code associated with onChange
is executed, resulting in an alert thanking the user for changing the value. Note that the code is contained in double quotes so that the system knows where the code ends. Note also that this code must use single quotes rather than double quotes for strings because the system thinks the code ends at the next double quote.
When the user clicks on the second button, the associated code is a function call to compute
, described below. The parameter is this.form
. The keyword this
refers to the object generating the event, in this case the button. The expression this.form
refers to the form containing the button. Similarly this.value
would refer to the value field of the button. Here is the code for compute
. As usual it is located in the header of the page.
function compute(form) { form.result.value = eval(form.expr.value); // eval evaluates arithmetic expressions }The function takes the value written in the text field named
expr
in the form, evaluates it, and stores the result in the value field of the text field named result
in the form. The function eval
used here is a built-in function in JavaScript which takes a legal arithmetic expression and evaluates it.
Functions are often used to handle events because it allows the user to lay out complex code in a more readable fashion than trying to write it as a long string.
Here are the definitions of functions used in our form example above. Recall that the function act
was called by act(this.form)
, so the parameter to act is the form containing the items.
function getAge(selectButton){ var index = selectButton.selectedIndex; return(selectButton[index].text); } function act(form) { if (form.cbLike.checked){ alert("Hey, "+form.name.value+", we\'re glad you liked this course! "+ "You are quite mature for being only "+getAge(form.age)+"."); } else { alert("Aw, we\'re disappointed! It must be because you are only "+ getAge(form.age) +"."); } }Let's start by looking at getAge. It takes as its parameter a selection button -- i.e., a pop-up menu. selectButton.selectedIndex returns the index of the item selected (a number ranging from 0 to one less than the number of options). The expression
selectButton[index].text
represents the label of the option selected in the menu. Thus getAge(selectButton)
returns the label of option selected in selectButton
.
The function act first checks to see if the checkbox cbLike is checked. If so it prints a message which uses the value stored in the name text field and the age of the person as obtained by using getAge on the age select button from the form. If it is not checked then a different message is printed.
To find more information on JavaScript, try the following tutorial:
Netscape JavaScript Guide at http://developer.netscape.com/docs/manuals/communicator/jsguide4/index.htm
.