|
|
Chapter 11
Having Fun with JavaScript
CONTENTS
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:
- Display each piece of the face in a separate frame while the
user is experimenting.
- Provide a button to build the complete face in a separate
window which the user can then print out or save as a complete
HTML file which displays the face.
- Provide a random face button which causes the script to build
a random face from among the possible faces.
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:
- You have fixed the number of available eyes, noses, and mouths
at four each. The program should be easily extendible to any number
of eyes, noses, and mouths, and the number of each feature should
be able to vary.
- Each time you build a face, it opens in the same window as
the last face you built. The program should open each face in
a different window.
- Users should be able to save the current face, and when they
first come to the page, that face should be loaded as the default
first face.
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>
- We still have one more addition to make: the ability to save
a face and have it displayed as the first face when the user returns
to the site. Extend the application so that there is a third button
at the bottom to save the current face and change the loading
procedure so that the saved face is loaded each time the user
arrives at the site.
- As you might have expected, the solution lies in cookies.
In the file build.htm, you
need to add a function called saveFace(),
which saves the three filenames in three separate cookies. Define
the path for the cookies to be "/"
so all the files in your application have access to the cookies.
Use Bill Dortch's cookie functions to handle the dirty work of
saving and retrieving the cookies.
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
<[email protected]>
// 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
<[email protected]>
// 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();">
|