In this chapter you are going to apply some of what you have learned to build a simple application that demonstrates how, with very basic JavaScript, it is possible to create the impression of a sophisticated interactive application.
You are going to design an application that enables users to build their own cartoon faces out of a library of existing eyes, noses, and mouths. No drawing skill is required for the user.
The application has several basic requirements:
In order to build this face program, you need to define the frameset, which contains all the elements of the interface and application.
To do this, use the frameset in Listing 11.1.
Listing 11.1. The parent frameset.
<FRAMESET ROWS="150,150,150,*">
<FRAMESET COLS="400,*">
<FRAME SRC="eye1.gif" NAME="eye" MARGINHEIGHT=0
MARGINWIDTH=0 SCROLLING="no">
<FRAME SRC="eyes.htm" MARGINHEIGHT=0 MARGINWIDTH=0 SCROLLING="auto">
</FRAMESET>
<FRAMESET COLS="400,*">
<FRAME SRC="nose1.gif" NAME="nose" MARGINHEIGHT=0
MARGINWIDTH=0 SCROLLING="no">
<FRAME SRC="noses.htm" MARGINHEIGHT=0 MARGINWIDTH=0 SCROLLING="auto">
</FRAMESET>
<FRAMESET COLS="400,*">
<FRAME SRC="mouth1.gif" NAME="mouth" MARGINHEIGHT=0
MARGINWIDTH=0 SCROLLING="no">
<FRAME SRC="mouths.htm" MARGINHEIGHT=0 MARGINWIDTH=0 SCROLLING="auto">
</FRAMESET>
<FRAME SRC="build.htm">
</FRAMESET>
This sets up a four-row grid. The top three rows are each divided into two columns: The left side displays the current selection for the eyes, nose, or mouth, and the right side presents all the available choices.
The bottom row is where the control buttons to build the face and generate a random face appear.
Based on this, you need to create four other HTML files (see Listings 11.2 through 11.5) which are the basis of the program: eyes.htm, noses.htm, mouths.htm and build.htm.
Listing 11.2. Source code for eyes.htm.
<!-- SOURCE CODE FOR eyes.htm -->
<HTML>
<BODY BGCOLOR="iceblue">
<TABLE BORDER=0>
<TR>
<TD><A HREF="eye1.gif" TARGET="eye">
<IMG SRC="eye1sample.gif" BORDER=0></A></TD>
<TD><A HREF="eye2.gif" TARGET="eye">
<IMG SRC="eye2sample.gif" BORDER=0></A></TD>
</TR>
<TR>
<TD><A HREF="eye3.gif" TARGET="eye"">
<IMG SRC="eye3sample.gif" BORDER=0></A></TD>
<TD><A HREF="eye4.gif" TARGET="eye">
<IMG SRC="eye4sample.gif" BORDER=0></A></TD>
</TR>
</TABLE>
</BODY>
</HTML>
Listing 11.3. The source code for noses.htm.
<!-- SOURCE CODE FOR noses.htm -->
<HTML>
<BODY BGCOLOR="iceblue">
<TABLE BORDER=0>
<TR>
<TD><A HREF="nose1.gif" TARGET="nose">
<IMG SRC="nose1sample.gif" BORDER=0></A></TD>
<TD><A HREF="nose2.gif" TARGET="nose">
<IMG SRC="nose2sample.gif" BORDER=0></A></TD>
</TR>
<TR>
<TD><A HREF="nose3.gif" TARGET="nose">
<IMG SRC="nose3sample.gif" BORDER=0></A></TD>
<TD><A HREF="nose4.gif" TAGRET="nose">
<IMG SRC="nose4sample.gif" BORDER=0></A></TD>
</TR>
</TABLE>
</BODY>
</HTML>
Listing 11.4. The source code for mouths.htm.
<!-- SOURCE CODE FOR mouths.htm -->
<HTML>
<BODY BGCOLOR="iceblue">
<TABLE BORDER=0>
<TR>
<TD><A HREF="mouth1.gif" TARGET="mouth">
<IMG SRC="mouth1sample.gif" BORDER=0></A></TD>
<TD><A HREF="mouth2.gif" TAGRET="mouth">
<IMG SRC="mouth2sample.gif" BORDER=0></A></TD>
</TR>
<TR>
<TD><A HREF="mouth3.gif" TARGET="mouth">
<IMG SRC="mouth3sample.gif" BORDER=0></A></TD>
<TD><A HREF="mouth4.gif" TARGET="mouth">
<IMG SRC="mouth4sample.gif" BORDER=0></A></TD>
</TR>
</TABLE>
</BODY>
</HTML>
The file build.htm (Listing 11.5) provides the controls in the bottom frame:
Listing 11.5. The source code for build.htm.
<!-- SOURCE CODE FOR build.htm -->
<HTML>
<HEAD>
<SCRIPT LANGUAGE="JavaScript">
<!-- HIDE FROM OTHER BROWSERS
// Build the complete face in a separate window
function buildFace() {
var eye = parent.eye.location;
var nose = parent.nose.location;
var mouth = parent.mouth.location;
var face = window.open("","builtFace","width=400,height=450");
face.document.open("text/html");
face.document.write('<IMG SRC="' + eye + '">');
face.document.write('<IMG SRC="' + nose + '">');
face.document.write('<IMG SRC="' + mouth + '">');
face.document.close();
}
// Build a random face in the current window
function randomFace() {
var eye = "eye" + getRandom() + ".gif";
var nose = "nose" + getRandom() + ".gif";
var mouth = "mouth" + getRandom() + ".gif";
parent.eye.location = eye;
parent.nose.location = nose;
parent.mouth.location = mouth;
}
// Generate a random number
function getRandom() {
today = new Date();
var bigNumber = today.getSeconds() * today.getTime() *
ÂMath.sqrt(today.getMinutes());
var randomNum = (bigNumber % 4) + 1;
return Math.floor(randomNum);
}
// STOP HIDING -->
</SCRIPT>
</HEAD>
<BODY BGCOLOR="#000000" TEXT="iceblue">
<FORM METHOD=POST>
<CENTER>
<INPUT TYPE="button" VALUE="Build This Face" onClick="buildFace();">
<INPUT TYPE="button" VALUE="Make A Random Face" onClick="randomFace();">
</CENTER>
</FORM>
</BODY>
</HTML>
The results of this application appear similar to Figures 11.1 and 11.2. |
Figure 11.1 : Choosing a facial feature updates the relevant frame on the left.
Figure 11.2 : Clicking on the build button causes a new window to open.
The first thing to notice about the four HTML documents is that three of them-eyes.htm, noses.htm, and mouths.htm-are very similar.
This is because all three files play the same role: They present options for the user to select each of three parts of the face.
Each file displays four options in a 2¥2 table. Each of the small images displayed is, in fact, a link targeted to the appropriate frame on the left. When the user clicks on one of the sample images, the full-size version of that feature is displayed in the corresponding frame on the left.
You use JavaScript in the build.htm document. Here you have three functions related to the two buttons displayed in the bottom frame of the frameset: buildFace(), randomFace(), and getRandom().
buildFace() and randomFace() are called by the event handlers of the two buttons:
<INPUT TYPE="button" VALUE="Build This Face" onClick="buildFace();">
<INPUT TYPE="button" VALUE="Make A Random Face" onClick="randomFace();">
The buildFace() function takes the three pieces of the face in the three frames and displays them in a single new window. This function needs to find out which files are displayed in each of the three left frames and then builds a single HTML file that displays the three files in a single window.
function buildFace() {
var eye = parent.eye.location;
var nose = parent.nose.location;
var mouth = parent.mouth.location;
var face = window.open("","builtFace","width=400,height=450");
face.document.open("text/html");
face.document.write('<IMG SRC="' + eye + '">');
face.document.write('<IMG SRC="' + nose + '">');
face.document.write('<IMG SRC="' + mouth + '">');
face.document.close();
}
The function starts by getting the URLs of the three selected facial features with the location property of the frame object, as in the example var eye = parent.eye.location;. You use the fact that you can address object properties by name in the structure parent.eye to reference each frame.
Once this is done, a new window of the desired size is opened using
var face =window.open("","builtFace","width=400,height=450");
This command specifies the size of the window in pixels using the optional windows attributes argument. The new object for this window is called face so that you can later use commands such as face.document.write().
After the window is open, open an HTML output stream using face.document.open("text/html") and then write out the three image tags based on the URLs you got earlier. Finally, you close the document output stream.
The randomFace() function simply selects three random facial features and then opens them in the appropriate frames. This is done by calling the getRandom() function, which returns a number from 1 to 4, and then building three filenames, such as
var eye = "eye" + getRandom() + ".gif".
function randomFace() {
var eye = "eye" + getRandom() + ".gif";
var nose = "nose" + getRandom() + ".gif";
var mouth = "mouth" + getRandom() + ".gif";
parent.eye.location = eye;
parent.nose.location = nose;
parent.mouth.location = mouth;
}
Once this is done, the three files are opened using window.open().
The getRandom() function is designed to return a random number from one to four. This is done by creating a new Date object for the current date and time, getting a large number by multiplying together different elements of the Date object, and then taking the modulus by four and adding one, as shown in the following lines.
function getRandom() {
today = new Date();
var bigNumber = today.getSeconds() * today.getTime() *
Math.sqrt(today.getMinutes());
var randomNum = (bigNumber % 4) + 1;
return Math.floor(randomNum);
}
The result is a pseudo-random number from one to four (because
the modulus returns a number greater than or equal to zero and
less than four). The use of Math.floor()
ensures that the number returned is an integer.
Note |
In Navigator 3, the Math.random() method could provide a random number. However, this will not work on all platforms in Navigator 2. |
There are a couple of limitations to the current script that you might like to improve:
In order to expand the script to support more than four choices for each feature, you need to make changes to each of the HTML files, including the parent frameset.
You start by adding a small script to the parent frameset (Listing 11.1).
<SCRIPT LANGUAGE="JavaScript">
<!-- HIDE FROM OTHER BROWSERS
var numEyes = 4;
var numNoses = 4;
var numMouths = 4;
// STOP HIDING -->
</SCRIPT>
This script is where you set the number of options for each of the three facial features. That way, if you want to add or remove choices, you only need to change these three numbers, and the whole program will work.
Next, you need to alter the three files eyes.htm, noses.htm, and mouths.htm (Listings 11.2 through 11.4) so that you use JavaScript to dynamically build two-row tables, regardless of the number of choices.
By way of example, this is what eyes.htm would look like:
<BODY BGCOLOR="iceblue">
<TABLE BORDER=0>
<TR>
<SCRIPT LANGUAGE="JavaScript">
<!-- HIDE FORM OTHER BROWSERS
for (var i = 1; i <= Math.floor(parent.numEyes / 2); i ++) {
document.write('<TD><A HREF="eye' + i + '.gif" TARGET="eye">');
document.write('<IMG SRC="eye' + i + 'sample.gif" BORDER=0></A></TD>');
}
// STOP HIDING -->
</SCRIPT>
</TR>
<TR>
<SCRIPT LANGUAGE="JavaScript">
<!-- HIDE FROM OTHER BROWSERS
for (var i = Math.floor(parent.numEyes / 2) + 1;
i <= parent.numEyes; i ++) {
document.write('<TD><A HREF="eye' + i + '.gif" TARGET="eye">');
document.write('<IMG SRC="eye' + i + 'sample.gif" BORDER=0></A></TD>');
}
// STOP HIDING -->
</SCRIPT>
</TR>
</TABLE>
</BODY>
What you have added are two short scripts that build the table cells for each row of the table. The first script builds cells for each image from the first to the halfway point in the available list, and the second builds from there to the end. You use Math.floor() to ensure that you are building filenames out of integer values.
Finally, you need to alter the randomFace() and getRandom() functions in build.htm (Listing 11.5). getRandom() now takes an argument which is the range it is supposed to return (that is, from 1 to num). randomFace() passes the appropriate variable from the parent frameset for each function call to getRandom().
function randomFace() {
var eye = "eye" + getRandom(parent.numEyes) + ".gif";
var nose = "nose" + getRandom(parent.numNoses) + ".gif";
var mouth = "mouth" + getRandom(parent.numMouths) + ".gif";
parent.eye.location = eye;
parent.nose.location = nose;
parent.mouth.location = mouth;
}
function getRandom(num) {
today = new Date();
var bigNumber = today.getSeconds() * today.getTime() *
Math.sqrt(today.getMinutes());
var randomNum = bigNumber % num + 1;
return Math.floor(randomNum);
}
In order to build each face in a new window, you need to make far fewer changes than you made to support the variable number of choices for each facial attribute.
All the changes are made to the file build.htm. You add a global variable called windowNumber, which you increment for each window you open. Then you make one change to the function buildFace() on the line where you open the window:
var face = window.open("","builtFace" + windowNumber ++,"width=400,height=450");
This builds a new window name based on the value of windowNumber
and then increments windowNumber
by one. Remember that the unary increment operator (++)
after an expression first evaluates the expression (in this case,
that is simply windowNumber)
and then increments the expression.
Note |
Navigator includes a special target _blank which, when used in conjunction with window.open(), opens a new window. For instance, window.open("","_blank") opens a new empty window. |
To help you see all the changes you have made, here is the source code including all the changes. I am only including eyes.htm (and not noses.htm or mouths.htm) because the changes are the same in these three files.
Listing 11.6. Final version of the application.
<!-- SOURCE CODE FOR PARENT FRAMESET -->
<HEAD>
<SCRIPT LANGUAGE="JavaScript">
<!-- HIDE FROM OTHER BROWSERS
var numEyes = 4;
var numNoses = 4;
var numMouths = 4;
// STOP HIDING -->
</SCRIPT>
</HEAD>
<FRAMESET ROWS="150,150,150,*">
<FRAMESET COLS="400,*">
<FRAME SRC="eye1.gif" NAME="eye" MARGINHEIGHT=0
MARGINWIDTH=0 SCROLLING="no">
<FRAME SRC="eyes.htm" MARGINHEIGHT=0 MARGINWIDTH=0 SCROLLING="auto">
</FRAMESET>
<FRAMESET COLS="400,*">
<FRAME SRC="nose1.gif" NAME="nose" MARGINHEIGHT=0
MARGINWIDTH=0 SCROLLING="no">
<FRAME SRC="noses.htm" MARGINHEIGHT=0 MARGINWIDTH=0 SCROLLING="auto">
</FRAMESET>
<FRAMESET COLS="400,*">
<FRAME SRC="mouth1.gif" NAME="mouth" MARGINHEIGHT=0
MARGINWIDTH=0 SCROLLING="no">
<FRAME SRC="mouths.htm" MARGINHEIGHT=0 MARGINWIDTH=0 SCROLLING="auto">
</FRAMESET>
<FRAME SRC="build.htm">
</FRAMESET>
<!-- SOURCE CODE FOR build.html -->
<HEAD>
<SCRIPT LANGUAGE="JavaScript">
<!-- HIDE FROM OTHER BROWSERS
var windowNumber = 1;
// Build the face in a separate window
function buildFace() {
var eye = parent.eye.location;
var nose = parent.nose.location;
var mouth = parent.mouth.location;
var face = window.open("","builtFace" +
windowNumber ++,"width=400,height=450");
face.document.open("text/html");
face.document.write('<IMG SRC="' + eye + '">');
face.document.write('<IMG SRC="' + nose + '">');
face.document.write('<IMG SRC="' + mouth + '">');
face.document.close();
}
// Display a random face in the current window
function randomFace() {
var eye = "eye" + getRandom(parent.numEyes) + ".gif";
var nose = "nose" + getRandom(parent.numNoses) + ".gif";
var mouth = "mouth" + getRandom(parent.numMouths) + ".gif";
parent.eye.location = eye;
parent.nose.location = nose;
parent.mouth.location = mouth;
}
// Generate a random number
function getRandom(num) {
today = new Date();
var bigNumber = today.getSeconds() * today.getTime() *
Math.sqrt(today.getMinutes());
var randomNum = Math.floor(bigNumber % num);
return randomNum + 1;
}
// STOP HIDING -->
</SCRIPT>
</HEAD>
<BODY BGCOLOR="#000000" TEXT="iceblue">
<FORM METHOD=POST>
<CENTER>
<INPUT TYPE="button" VALUE="Build This Face" onClick="buildFace();">
<INPUT TYPE="button" VALUE="Make A Random Face" onClick="randomFace();">
</CENTER>
</FORM>
</BODY>
<!-- SOURCE CODE FOR eyes.html -->
<BODY BGCOLOR="iceblue">
<TABLE BORDER=0>
<TR>
<SCRIPT LANGUAGE="JavaScript">
<!-- HIDE FORM OTHER BROWSERS
for (var i = 1; i <= Math.floor(parent.numEyes / 2); i ++) {
document.write('<TD><A HREF="eye' + i + '.gif" TARGET="eye">');
document.write('<IMG SRC="eye' + i + 'sample.gif" BORDER=0></A></TD>');
}
// STOP HIDING -->
</SCRIPT>
</TR>
<TR>
<SCRIPT LANGUAGE="JavaScript">
<!-- HIDE FROM OTHER BROWSERS
for (var i = Math.floor(parent.numEyes / 2) + 1;
i <= parent.numEyes; i ++) {
document.write('<TD><A HREF="eye' + i + '.gif" TARGET="eye">');
document.write('<IMG SRC="eye' + i + 'sample.gif" BORDER=0></A></TD>');
}
// STOP HIDING -->
</SCRIPT>
</TR>
</TABLE>
</BODY>
Next, extend the parent frameset file so that it loads a blank file into each of three frames on the left and then uses an onLoad event handler to call a function called loadFace() to retrieve the relevant cookies and load the files into the empty frames.
The resulting HTML documents look like Listing 11.7.
Listing 11.7. The final version of the parent frameset.
<!-- SOURCE CODE OF PARENT FRAMESET -->
<HEAD>
<SCRIPT LANGUAGE="JavaScript">
<!-- HIDE FROM OTHER BROWSERS
//
// Cookie Functions - Second Helping (21-Jan-96)
// Written by: Bill Dortch, hIdaho Design <bdortch@netw.com>
// The following functions are released to the public domain.
//
// "Internal" function to return the decoded value of a cookie
//
function getCookieVal (offset) {
var endstr = document.cookie.indexOf (";", offset);
if (endstr == -1)
endstr = document.cookie.length;
return unescape(document.cookie.substring(offset, endstr));
}
//
// Function to return the value of the cookie specified by "name".
// name - String object containing the cookie name.
// returns - String object containing the cookie value, or null if
// the cookie does not exist.
//
function GetCookie (name) {
var arg = name + "=";
var alen = arg.length;
var clen = document.cookie.length;
var i = 0;
while (i < clen) {
var j = i + alen;
if (document.cookie.substring(i, j) == arg)
return getCookieVal (j);
i = document.cookie.indexOf(" ", i) + 1;
if (i == 0) break;
}
return null;
}
//
// Function to create or update a cookie.
// name - String object object containing the cookie name.
// value - String object containing the cookie value. May contain
// any valid string characters.
// [expires] - Date object containing the expiration data of the cookie.
// If omitted or null, expires the cookie at the end of the current
Âsession.
// [path] - String object indicating the path for which the cookie is
Âvalid.
// If omitted or null, uses the path of the calling document.
// [domain] - String object indicating the domain for which the cookie
// is valid. If omitted or null, uses the domain of the calling
Âdocument.
// [secure] - Boolean (true/false) value
Âindicating whether cookie transmission
// requires a secure channel (HTTPS).
//
// The first two parameters are required. The others, if supplied, must
// be passed in the order listed above. To omit an unused optional field,
// use null as a place holder. For example, to call SetCookie using name,
// value and path, you would code:
//
// SetCookie ("myCookieName", "myCookieValue", null, "/");
//
// Note that trailing omitted parameters do not require a placeholder.
//
// To set a secure cookie for path "/myPath", that expires after the
// current session, you might code:
//
// SetCookie (myCookieVar, cookieValueVar, null, "/myPath", null,
Âtrue);
//
function SetCookie (name, value) {
var argv = SetCookie.arguments;
var argc = SetCookie.arguments.length;
var expires = (argc > 2) ? argv[2] : null;
var path = (argc > 3) ? argv[3] : null;
var domain = (argc > 4) ? argv[4] : null;
var secure = (argc > 5) ? argv[5] : false;
document.cookie = name + "=" + escape (value) +
((expires == null) ? "" : ("; expires=" + expires.toGMTString())) +
((path == null) ? "" : ("; path=" + path)) +
((domain == null) ? "" : ("; domain=" + domain)) +
((secure == true) ? "; secure" : "");
}
// Function to delete a cookie. (Sets expiration date to current date/
Âtime)
// name - String object containing the cookie name
//
function DeleteCookie (name) {
var exp = new Date();
exp.setTime (exp.getTime() - 1); // This cookie is history
var cval = GetCookie (name);
document.cookie = name + "=" + cval + "; expires=" + exp.toGMTString();
}
var numEyes = 4;
var numNoses = 4;
var numMouths = 4;
function loadFace() {
var eye = GetCookie("eye");
if ((eye == null) || (eye == "")) { eye = "eye1.gif"; }
parent.eye.location = eye;
var nose = GetCookie("nose");
if ((nose == null) || (nose == "")) { nose = "nose1.gif"; }
parent.nose.location = nose;
var mouth = GetCookie("mouth");
if ((mouth == null) || (mouth == "")) { mouth = "mouth1.gif"; }
parent.mouth.location = mouth;
}
// STOP HIDING -->
</SCRIPT>
</HEAD>
<FRAMESET ROWS="150,150,150,*" onLoad="loadFace();">
<FRAMESET COLS="400,*">
<FRAME SRC="blank.htm" NAME="eye" MARGINHEIGHT=0
ÂMARGINWIDTH=0 SCROLLING="no">
<FRAME SRC="eyes.htm" MARGINHEIGHT=0 MARGINWIDTH=0 SCROLLING="auto">
</FRAMESET>
<FRAMESET COLS="400,*">
<FRAME SRC="blank.htm" NAME="nose" MARGINHEIGHT=0
ÂMARGINWIDTH=0 SCROLLING="no">
<FRAME SRC="noses.htm" MARGINHEIGHT=0 MARGINWIDTH=0 SCROLLING="auto">
</FRAMESET>
<FRAMESET COLS="400,*">
<FRAME SRC="blank.htm" NAME="mouth" MARGINHEIGHT=0
ÂMARGINWIDTH=0 SCROLLING="no">
<FRAME SRC="mouths.htm" MARGINHEIGHT=0 MARGINWIDTH=0 SCROLLING="no">
</FRAMESET>
<FRAME SRC="build.htm">
<SCRIPT LANGUAGE="JavaScript">
<!-- HIDE FROM OTHER BROWSERS
// STOP HIDING -->
</SCRIPT>
</FRAMESET>
Listing 11.8. Revised version of build.htm.
<!-- SOURCE CODE FOR build.html -->
<HEAD>
<SCRIPT LANGUAGE="JavaScript">
<!-- HIDE FROM OTHER BROWSERS
//
// Cookie Functions - Second Helping (21-Jan-96)
// Written by: Bill Dortch, hIdaho Design <bdortch@netw.com>
// The following functions are released to the public domain.
//
//
// "Internal" function to return the decoded value of a cookie
//
function getCookieVal (offset) {
var endstr = document.cookie.indexOf (";", offset);
if (endstr == -1)
endstr = document.cookie.length;
return unescape(document.cookie.substring(offset, endstr));
}
//
// Function to return the value of the cookie specified by "name".
// name - String object containing the cookie name.
// returns - String object containing the cookie value, or null if
// the cookie does not exist.
//
function GetCookie (name) {
var arg = name + "=";
var alen = arg.length;
var clen = document.cookie.length;
var i = 0;
while (i < clen) {
var j = i + alen;
if (document.cookie.substring(i, j) == arg)
return getCookieVal (j);
i = document.cookie.indexOf(" ", i) + 1;
if (i == 0) break;
}
return null;
}
//
// Function to create or update a cookie.
// name - String object object containing the cookie name.
// value - String object containing the cookie value. May contain
// any valid string characters.
// [expires] - Date object containing the expiration data of the cookie.
// If omitted or null, expires the cookie at the end of the
// current session.
// [path] - String object indicating the path for which the cookie is
// valid.
// If omitted or null, uses the path of the calling document.
// [domain] - String object indicating the domain for which the cookie
// is valid. If omitted or null, uses the domain of the calling
// document.
// [secure] - Boolean (true/false) value
// indicating whether cookie transmission
// requires a secure channel (HTTPS).
//
// The first two parameters are required. The others, if supplied, must
// be passed in the order listed above. To omit an unused optional field,
// use null as a place holder. For example, to call SetCookie using name,
// value and path, you would code:
//
// SetCookie ("myCookieName", "myCookieValue", null, "/");
//
// Note that trailing omitted parameters do not require a placeholder.
//
// To set a secure cookie for path "/myPath", that expires after the
// current session, you might code:
//
// SetCookie (myCookieVar, cookieValueVar, null, "/myPath", null,
// true);
//
function SetCookie (name, value) {
var argv = SetCookie.arguments;
var argc = SetCookie.arguments.length;
var expires = (argc > 2) ? argv[2] : null;
var path = (argc > 3) ? argv[3] : null;
var domain = (argc > 4) ? argv[4] : null;
var secure = (argc > 5) ? argv[5] : false;
document.cookie = name + "=" + escape (value) +
((expires == null) ? "" : ("; expires=" + expires.toGMTString())) +
((path == null) ? "" : ("; path=" + path)) +
((domain == null) ? "" : ("; domain=" + domain)) +
((secure == true) ? "; secure" : "");
}
// Function to delete a cookie. (Sets expiration date to current date/
// time)
// name - String object containing the cookie name
//
function DeleteCookie (name) {
var exp = new Date();
exp.setTime (exp.getTime() - 1); // This cookie is history
var cval = GetCookie (name);
document.cookie = name + "=" + cval + "; expires=" + exp.toGMTString();
}
var windowNumber = 1;
function buildFace() {
var eye = parent.eye.location;
var nose = parent.nose.location;
var mouth = parent.mouth.location;
var face = window.open("","builtFace" +
windowNumber ++,"width=400,height=450");
face.document.open("text/html");
face.document.write('<IMG SRC="' + eye + '">');
face.document.write('<IMG SRC="' + nose + '">');
face.document.write('<IMG SRC="' + mouth + '">');
face.document.close();
}
function randomFace() {
var eye = "eye" + getRandom(parent.numEyes) + ".gif";
var nose = "nose" + getRandom(parent.numNoses) + ".gif";
var mouth = "mouth" + getRandom(parent.numMouths) + ".gif";
parent.eye.location = eye;
parent.nose.location = nose;
parent.mouth.location = mouth;
}
function getRandom(num) {
today = new Date();
var bigNumber = today.getSeconds() * today.getTime() *
Math.sqrt(today.getMinutes());
var randomNum = Math.floor(bigNumber % num);
return randomNum + 1;
}
function saveFace() {
var eye = parent["eye"].location;
var nose = parent["nose"].location;
var mouth = parent["mouth"].location;
var expiry = new Date;
expiry.setTime(expiry.getTime() + 365*24*60*60*1000);
SetCookie("eye",eye,expiry,"/");
SetCookie("nose",nose,expiry,"/");
SetCookie("mouth",mouth,expiry,"/");
}
// STOP HIDING -->
</SCRIPT>
</HEAD>
<BODY BGCOLOR="#000000" TEXT="iceblue">
<FORM METHOD=POST>
<CENTER>
<INPUT TYPE="button" VALUE="Build This Face" onClick="buildFace();">
<INPUT TYPE="button" VALUE="Make A Random Face" onClick="randomFace();">
<INPUT TYPE="button" VALUE="Save This Face" onClick="saveFace();">
</CENTER>
</FORM>
</BODY>
You may also want to extend the form in build.htm to add a button to load a saved face:
<INPUT TYPE="button" VALUE="Load Saved Face" onClick="parent.loadFace();">