Given by Geoffrey C. Fox, Tom Scavo at UC Web applications Certificate on Summer 97. Foils prepared 23 June 1997
Outside Index
Summary of Material
Java versus JavaScript versus HTML issues |
Some simple motivating JavaScript examples |
Language features and syntax |
JavaScript's object model Ñ methods and properties |
Arrays (old and new) in JavaScript |
Method arguments |
with and other object-related syntax |
Built-in objects: Array, Date, Math, Object, String |
Navigator objects: window, document, location, etc. |
Property arrays: frames, anchors, forms, images, etc. |
Event handling including Function object |
Cookies |
User objects and Examples including using JavaScript for frames |
Outside Index
Summary of Material
See: |
http://www.npac.syr.edu/users/gcf/uccjavascript97 |
Instructors: Geoffrey Fox and Tom Scavo |
Syracuse University |
111 College Place |
Syracuse, New York 13244-4100 |
Java versus JavaScript versus HTML issues |
Some simple motivating JavaScript examples |
Language features and syntax |
JavaScript's object model Ñ methods and properties |
Arrays (old and new) in JavaScript |
Method arguments |
with and other object-related syntax |
Built-in objects: Array, Date, Math, Object, String |
Navigator objects: window, document, location, etc. |
Property arrays: frames, anchors, forms, images, etc. |
Event handling including Function object |
Cookies |
User objects and Examples including using JavaScript for frames |
Historically, JavaScript was called LiveScript, which was developed by Netscape with some of the same goals as Java but focused on a "smaller world" Ñ manipulation of text and objects connected with Netscape clients |
Markup Language ............................. Programming Language |
Ñ> HTML JavaScript Java C++ <Ñ |
In some cases, we use JavaScript as an alternative to Java where the "rapid prototyping" of a fully scripted language is helpful
|
JavaScript can be thought of as Java with the AWT (Abstract Windowing Toolkit) replaced by Netscape Client
|
JavaScript is particularly useful for multi-frame windows and for manipulating forms without complex (server-side) CGI scripts |
As a client-side programming language, JavaScript can be much faster than a CGI-based form, which has inevitable delays as required by server-client communication and invocation of a new process on the server side
|
This increase in client-side processing speed is essential in some applications since users will not accept long delays (several seconds) in response to simple mouse clicks |
Java is a broad industry standard, which has been carefully designed and is well documented |
JavaScript (originally from Netscape, but supported by Microsoft) has a mediocre design and is poorly documented |
Typical Java applet structure
|
Typical JavaScript structure
|
Note in each case , Java and JavaScript use "runtime", which is "compiled, high-performance library" (probably written in C and C++) |
Execute C code instruction Ñ 1 clock cycle ( 10^8 per sec) |
Run a client-side C subroutine Ñ can do up to 10^6 instructions in time that is significant for user (few milliseconds) |
JavaVM interpreter Ñ roughly 50 times slower than C |
JavaVM Just in Time compiler (effectively compile JavaVM in real time) Ñ roughly 2Ð8 times slower than C |
Native Java compiler Ñ same speed as C |
Perl interpreter (processes entire program before interpreting) Ñ 500 times slower than C except in runtime |
Tcl, JavaScript "true" interpreters Ñ 5000 times slower than C
|
CGI script Ñ server, network, and client HTML page regeneration delay measured in seconds |
Like most interpreters (look at Basic manual) JavaScript has a huge and growing number of "basic" methods and objects |
To study JavaScript, we will have to use some relatively advanced HTML features including
|
<HTML> |
<HEAD> |
<TITLE>A JavaScript Example</TITLE> |
</HEAD> |
<BODY> |
<SCRIPT LANGUAGE="JavaScript"> |
<!-- a comment to hide JavaScript from old browsers |
document.writeln("<H1>Hello World!</H1>"); |
// end script hiding --> |
</SCRIPT> |
<B>Continue with conventional HTML</B> |
</BODY></HTML> |
There is only one real JavaScript statement here, namely |
document.writeln("textstring"); |
This statement outputs into current page the quoted text followed by a newline |
Note the rather peculiar way we "hide" JavaScript from browsers that don't understand it by inserting a conventional HTML comment: |
<SCRIPT LANGUAGE="JavaScript"> |
<!-- a comment to hide JavaScript from old browsers |
// Insert JavaScript statements here |
// end script hiding --> |
</SCRIPT> |
Depending on your needs, JavaScript may be written in <HEAD> or <BODY> section of HTML document |
<HTML><HEAD><TITLE>JavaScript with Forms</TITLE> |
<SCRIPT LANGUAGE="JavaScript"> |
<!-- a comment to hide JavaScript from old browsers |
function compute(form) { |
if (confirm("Is this what you want?")) |
form.result.value = eval(form.expr.value); |
else alert("Enter a new expression then!"); |
} |
// end script hiding --> |
</SCRIPT></HEAD> |
<BODY><FORM> |
Enter an expression: |
<INPUT TYPE="text" NAME="expr" SIZE=15> |
<INPUT TYPE="button" VALUE="DoIt!" ONCLICK="compute(this.form)"> |
<BR>Result: <INPUT TYPE="text" NAME="result" SIZE=15><BR> |
</FORM></BODY></HTML> |
Enter an expression: 9+5 |
Result: 14 |
confirm is a native JavaScript method that pops up a window, requesting confirmation from the user |
alert is a native JavaScript method that pops up a window with a message requiring the user to click OK |
onClick="Javascript Statement Block" causes the statement block to be executed when the button is clicked |
<HTML><HEAD><TITLE>Parameterized HTML</TITLE> |
<SCRIPT LANGUAGE="JavaScript"> |
<!-- A comment to hide JavaScript from old browsers |
var imagewidth=600; // Variables could be input |
var imagefile="npac.gif"; // in a form or computed... |
// end script hiding --> |
</SCRIPT></HEAD> |
<BODY> É Bunch of normal stuff |
<SCRIPT LANGUAGE="JavaScript" > |
<!-- A comment to hide JavaScript from old browsers |
document.writeln('<img align=top width=' + imagewidth + ' src="' + imagefile + '" >'); |
// end script hiding --> |
</SCRIPT> |
É Yet more normal stuff |
</BODY></HTML> |
Note single quotes used for JavaScript, double quotes for HTML -- can use \' if necessary to hide special meaning from JavaScript |
Netscape servers now support the "LiveWire" extension which allows you to write "CGI Programs" in JavaScript |
One can specify different versions of the JavaScript language
|
location.replace(URL) replaces current page with new URL which in this case is assumed to hold a version with nifty new JavaScript 1.1 features |
This foilset assumes JavaScript 1.1 except in few cases such as arrays where we also describe older 1.0 syntax. |
<NOSCRIPT> É </NOSCRIPT> specifies what to do if user has disabled JavaScript in Options menu (due to security perhaps!) |
One can read JavaScript from a file: |
<SCRIPT SRC="JSLibrary.js"> |
document.write("JSLibrary.js not found!"); // The body of <SCRIPT> is executed ONLY |
// if JSLibrary.js is NOT found! |
</SCRIPT> |
The included file must have .js suffix and server must be set up with correct MIME types to download .js files |
One can demonstrate JavaScript as an interpreter by typing javascript: into location field of your browser.
|
One can execute arbitrary JavaScript code in anchors and other tags:
|
The JavaScript Guide describes some interesting examples, including this client-side image map:
|
One can parameterize HTML using document.writeln() |
commands such as: |
document.writeln("str1" + JSvariable + "str2"); |
Another way of achieving this is by directly embedding the variable into the HTML, requiring no <SCRIPT> tag and no document.write(): |
<IMG WIDTH="&{JSvar1};" SRC="&{JSvar2};"> |
where JSvar1 and JSvar2 are JavaScript variables |
Syntax is modeled after HTML special characters: for example, > produces a literal greater than sign (>) |
Such JavaScript entities can ONLY appear on the right-hand side of attribute value pairs
|
JavaScript: Interpreted and not compiled by client or server |
Java: Compiled bytecodes downloaded from server and interpreted or (Just in Time) compiled by client |
JavaScript: Object-based, but no classes or inheritance |
Java: Object-oriented class structure with (single) inheritance |
JavaScript: Code typically integrated with or embedded in HTML (SRC="File.js" is exception) |
Java: Applets distinct from HTML and accessed by <APPLET> tag from HTML page |
JavaScript: User has full access to capabilities of Navigator and functionality of window components |
Java: User relies on Java AWT (or perhaps HotJava browser) for user interface components |
JavaScript: No explicit data types (loosely typed) |
Java: Variable data types must be declared and carefully "cast" to convert from one type to another (strong typing) |
JavaScript: Dynamic bindingÑobject references are interpreted at runtime (typical interpreted behavior) |
Java: Static bindingÑobject references are resolved at compile time |
Security: Today JavaScript and Java applets have significant security restrictions. This is a (Netscape) runtime and not a language feature! |
JavaScript only has one simple type, namely: |
var anumber = 137; // use var to define a number |
var astring = "1"; // or to define a string |
Loose typing in JavaScript allows interpreter to creatively interpret an expression. Note that strings take precedence over numbers: |
var x = astring + anumber; // results in x = "1137" |
(Early versions of JS inferred the type from the leftmost variable.) |
Use parseInt and parseFloat to extract numerical values from strings |
Note special value null (no quotes) can be used as a null value |
Strings can be delimited by '..text..' or "..text.." which are identical in meaning (unlike PERL). Also, one can use \n for newline and \t for tab (and a few others). |
Boolean literals are either true or false |
Comments come in two flavors: |
/* any text including newlines */ |
statements; // comment terminated by newline |
JavaScript expressions and basic operators are similar to C, PERL, and Java |
Assignment operators: |
= += -= *= /= %= <<= >>= >>>= &= ^= |=
|
Conditional expressions are supported:
|
Arithmetic operators are as usual with the addition of ++ and --
|
Bitwise logical operators: & (AND) | (OR) ^ (XOR) operate on two numbers expressed in 32-bit integer form and perform indicated logical operation on each bit separately |
<< is bitwise left shift discarding bits at left (high order) and zero filling at right |
>> is bitwise right shift propagating the sign bit in high order (position 31) |
>>> is zero fill right shift with no special treatment of sign bit |
Boolean operators are && (AND), || (OR), ! (NOT) and can only operate on boolean variables that are true or false |
Relational operators are == > >= < <= != which can be used on numeric or string variables |
Concatenation operator (+) joins two strings together: |
x = "Hello "; y = "World!"; |
// x + y is "Hello World!"
|
if statements must have multiple statements inside curly braces: |
if ( condition ) { |
statement1; statement2; |
} else { // optional of course |
statement3; statement4; |
} |
Note: there is no else if construct |
for and while are essentially the same as in Java: |
for ( init-exp; condition; incr-exp ) { |
statement1; statement2; |
} |
while ( condition ) { |
statement1; statement2; |
} |
break and continue in for and while loops are permitted. Named break as in Java or PERL are not supported. |
JavaScript has a simple object-oriented structure without any inheritance ( a major difference from Java) |
JavaScript has a rather confused syntax for defining objects, which mixes the role of class, function, and constructor! |
An object is a container with properties and methods inside it. |
Variables or other objects inside an object are called properties |
Functions inside an object are called methods |
Arrays are defined as properties inside an object |
Multidimensional arrays are arrays, which themselves have properties that are arrays |
Variables are written in object-oriented fashion: |
parentobject.prop1[index1].prop2..propN[indexN] |
There is no hierarchical inheritance in object definitions, but the ability to define object properties that are themselves objects creates a natural hierarchical naming scheme |
Object methods are naturally referred to as |
object...property.method(arguments) |
Methods, objects, and properties are naturally divided into those defined by Navigator and those defined by the user. |
Here is an example of a Navigator object with a typical property and method
|
top.setFrame("help.html","mainDisplay"); |
function setFrame(relativeURL,frameName) { |
var actualURL = top.baseURL + relativeURL; |
top.frames[frameName].location.href =
|
} |
top refers to the top-level window in a frameset document. It has a property called frames, which is an array labeled by integers or by name as in <frame> name="frameName" </frame> tag |
Setting a URL into the location.href property of a frame loads that page into the given frame |
Use this.actualURL to distinguish local variable actualURL from a global variable of the same name |
Put these functions in <head> </head> container to ensure they are loaded before anything else |
You define a class template (to use Java lingo) with a function definition and then create an instance of the object with the new statement: |
function MenuObject(no, name) { |
this.no = no; // Give instance a numerical label |
this.name = name; // Label this particular menu |
this.color = 'black'; |
this.menuSelection = 1; |
this.count = 0; |
this.options = new Array(); // To be discussed |
} |
Define two menu instances: |
worldMenu = new MenuObject(1, 'world'); |
familyMenu = new MenuObject(2, 'family'); |
Object properties are accessed in natural o-o fashion: |
var actualSelected = worldMenu.menuSelection; |
familyMenu.color = 'red'; |
Curiously, in Netscape 2 you can also use array-like notation:
|
We will return to this when we discuss arrays |
One associates methods with user-defined objects, but with a syntax that appears very limiting since object methods have identical arguments to constructor function |
General syntax is: |
ObjectName.methodName = functionName; |
where ObjectName is an existing object and functionName is an existing function Ñ it can be used to set event handlers with no arguments! |
with ( ParticularObject ) { |
// any old statements É |
} |
Within the curly braces, ParticularObject is the default object for any property or method that does not specify a parent object |
with (Math) { // An example |
area = PI*r*r; // Math property PI |
x = r*cos(theta); // Math method cos |
y = r*sin(theta); // Math method sin |
} |
One can iterate over all properties of an object: |
for ( variable in object ) { É } |
function dump_props(obj, obj_name) { |
var result = ""; |
for ( var i in obj ) {
|
} |
return result + "<HR>"; |
} |
Here i is an index and obj[i] is the actual property |
Note user supplies obj and obj_name: |
function car(make, model) { // An Example |
this.make = make; this.model = model; |
} |
mycar = new car("Ford", "Explorer"); |
document.writeln(dump_props(mycar, "mycar")); |
In Navigator 3, we write: |
var area = new Array(); |
area[0] = "Alabama"; |
area[1] = "Alabama"; |
area[2] = "Alaska"; // etc. |
var acode = new Array(); |
acode[0] = 205; // mapping area codes to states |
acode[1] = 334; |
acode[2] = 907; |
area.length gives the length of the array ( 3 in this case) |
Note you can set array elements to be objects to make arrays of objects: |
menuArray = new Array(); |
menuArray[0] = new MenuObject(1, 'world'); |
worldMenu = menuArray[0]; // a synonym |
This is the old way of defining arrays and the only way allowed in Navigator 2: |
function MakeArray(size) { |
this.length = size; |
for( var i = 1; i <= size; i++ ) {
|
} |
} |
This gives arrays where you must predefine a size (a problem) and where arrays count from 1 not 0 (an artifact of MakeArray setting this.length = size at start not end of function). The latter "feature" could lead to great joy for Fortran programmers! |
One can easily define and use multidimensional arrays:
|
Arrays (in NN 3.0) have some interesting methods:
|
myArray = new Array(InitSize,val0,val1,...); |
specifies an initial size and initial values of the array. The arguments are optional and undefined initial values are set to null. |
function foo(x1, x2) { |
// the arguments array: |
var argv = foo.arguments; |
// number of arguments (same as argv.length): |
var n = foo.arguments.length; |
// y1 is same as this.x1 or argv[0]: |
var y1 = foo.arguments[0]; |
// the last argument (same as argv[n-1]): |
var yn = foo.arguments[n-1]; |
// use inside function to determine caller: |
var wherefrom = foo.caller; |
} |
This allows one to process functions with a variable number of arguments |
The arguments array is a property of all user-defined functions and Function objects. |
The this keyword is very useful but confusing since it's not always clear what it refers to
|
Here is an example that sets the URL for a link: |
function setURL(obj) { // Put in <head> container |
obj.target = "Desiredframe"; // set frame |
obj.href = "http://www.npac.syr.edu"; // set URL |
} |
In the body of the HTML document: |
<a href="" onClick="setURL(this)" onMouseOver="window.status='URL set dynamically in method setURL'; return true">Click Here for Dynamic URL</a> |
Here this refers to a link object created by <a>..</a> |
window.status is line at bottom, which usually records URL |
Note setURL overrides href specified in <a> tag |
There are JavaScript functions (not string methods) that convert strings to numbers |
parseInt("15") or equivalently parseInt("15",10) both return the number 15 in base 10 |
The optional second argument is the desired radix so that parseInt("15",8) returns 17 in octal |
If input string begins with "0x" the default radix is 16 (hexadecimal) whereas if it begins with "0" the default radix is 8 (octal) Ñ otherwise, the default radix is 10 |
x = 1 + "1"; // evaluates to "11" |
x = 1 + parseInt("1"); // evaluates to 2 |
parseFloat(string) returns a floating point value
|
On platforms that support it, parseInt and parseFloat return NaN (Not a Number) if parsing fails |
eval is an important function that lets you evaluate JavaScript code on-the-fly |
For instance, document.forms[0].myName.value is the value of a form element: |
<INPUT TYPE="text" NAME="myName" VALUE="value" onChange="handle(this.name)"> |
this.name holds myName as an ASCII string: |
var x = document.forms[0].myName.value; // No! |
var s = "document.forms[0]." + myName + ".value"; |
var x = eval(s); // Yes! |
That is, eval applies the JavaScript interpreter to its argument |
This can be used to copy information between forms as in |
eval("document.forms[1]." + myName + ".defaultvalue") |
= eval("document.forms[0]." + myName + ".value") |
For a long time, eval didn't work right, so check your browser! |
Some JavaScript objects are associated with Navigator (window, document, etc.) and the LiveWire server |
There are also numerous built-in objects (included in LiveWire as well):
|
We have described Array and will ignore Boolean |
We review the others in the followingÉ |
Math has a set of properties (built-in constants) including |
E, LN10, LN2, PI, SQRT1_2, and SQRT2. For example: |
Math.PI is equal to 3.14159É |
Math methods include the usual ones: |
Math.abs(x) returns the absolute value of x |
Math.max(x1,x2) returns the maximum of x1 and x2 |
Math.cos(x) returns the cosine of x (given in radians) |
Math.round(x) rounds x to the nearest integer |
Math.pow(2, 0.5) is equivalent to Math.sqrt(2) |
The Number object has properties defining system dependent constants such as:
|
Any constant such as "Hello World!" or a variable holding text is a String object in JavaScript. For example: |
/* Add stem to newurl if the latter is a relative |
address. Stem must end with a slash. */ |
function checkurl(stem, newurl) { |
var len = newurl.length; // length property of String |
var stemlen = stem.length; |
if ( len < 7 )
|
var grab = newurl.substring(0,6); // first six chars |
if( (grab == "ftp://") || (grab == "http:/") )
|
return (stem + newurl); |
} |
function seturl(name) { |
var addr = "http://www.npac.syr.edu/users/gcf/wisdom/"; |
name.href = checkurl(addr, "List.html"); |
} |
The String object has one property: |
myString.length gives string length in characters |
JavaScript has only one type of String object, whereas Java has both String (fixed) and StringBuffer (mutable) classes |
Characters are indexed from the left starting at 0 and ending with myString.length - 1 |
newstring = myString.substring(pos1,pos2); |
returns the substring in position pos1 ... pos2 - 1 |
Peculiarly, if pos2 < pos1, the previous statement returns the substring in position pos2 ... pos1 - 1 |
/* Given two linked comma-separated strings containing parameter |
names and values for an applet, return the corresponding HTML */ |
function commaseparated(appletpname,appletpvalue) { |
var stop = appletpname.lastIndexOf(','); // last comma |
if( appletpname.length <= 0 ) |
stop = -2; // length is property of String object |
index = -1; |
var ct = 0; // this is a precaution |
var jndex1 = 0; |
var jndex = -1; |
while( index <= stop) { // scan through commas |
index1 = appletpname.indexOf(',', index+1); // next comma |
if (index1 < 0 ) index1 = appletpname.length; // no more commas |
++ct; |
if ( ct > 20 ) break; |
jndex1 = appletpvalue.indexOf(',', jndex+1); |
if ( jndex1 < 0 ) jndex1 = appletpvalue.length; |
// Extract the stuff between commas |
var grab1 = appletpname.substring(index+1, index1); |
var grab2 = appletpvalue.substring(jndex+1, jndex1); |
var tag = '<param name=' + grab1 + ' value="' + grab2 + '">'; |
top.document.writeln(tag); |
index = index1; |
jndex = jndex1; |
} |
} |
We introduce two new methods: |
myString.IndexOf(lookfor); |
where myString and lookfor are any strings |
IndexOf returns the position of a character in myString that begins a substring exactly matching lookfor: |
var s = "http://www.npac.syr.edu"; |
s.IndexOf("www"); // returns 7 |
myString.IndexOf(lookfor, searchfrom); |
where searchfrom specifies the starting position of the search (see the previous foil for an example) |
myString.lastIndexOf(lookfor, lastsearchfrom); |
is similar to IndexOf but starts from the end of the string |
Default value of lastsearchfrom is myString.length - 1 |
IndexOf and lastIndexOf return -1 if requested string is not found |
JavaScript really needs the powerful text processing capabilities of PERL. (Lets hope either Netscape adds them or somebody builds them.) On the other hand, JavaScript (like Java) has 21 built-in methods associated with the Date object! |
today = new Date(); // current Date and Time |
now = new Date("February 26, 1996 15:13:00"); /* sets now to date/time these notes were prepared! */ |
Both Java and JavaScript store dates internally as number of elapsed milliseconds since January 1, 1970 00:00:00. |
In a Java, Date.UTC(date as bunch of numbers) and Date.parse(date as a text string) are static methods |
There are methods such as getMonth that extract the month from a date |
See the online resource for all possible methods! |
Note window is a basic concept and frame is a child of window of the same object type |
The JavaScript hierarchy may be illustrated as follows: |
top.frames[frameIndex].document. |
forms[formIndex].elementName.value |
where frameIndex and formIndex are usually numbers |
The frames array may also be indexed by name. For example, frames["frameName"] is sometimes more convenient
|
window and Frame are objects reflecting hierarchy |
document, Form, history, Link, and location are objects defining parts of a window or frame |
anchors, links, forms, frames, applets, and images are property arrays |
top, parent, and self are properties of frames and windows |
All of the above are defined within a single browser window |
opener is a property of window, which contains the name of the window that called open to create the current window |
top is frameset containing three grey windows while parent is one with three red frames |
childw is frameset in new browser window shown in brown |
The window object has a method open, which creates a new window. This is equivalent to clicking "New Web Browser" on the File menu |
childw = window.open(URL, Name, Features); |
Features is a set of comma-separated options such as:
|
A script in a spawned window can access properties of the originating window with top.opener |
JavaScript can help various frames talk to each other, but one sometimes needs dummy frames to preserve JavaScript between pages |
In Java AWT we learned about hierarchical layout schemes Ñ in Netscape 2.0 world the containers in which subcomponents are laid out are frames and forms within frames
|
<HTML> |
<HEAD>...</HEAD> |
<FRAMESET ROWS="10%,80%,10%"> |
<FRAME SRC="header.html"> |
<FRAMESET COLS="30%,70%">
|
</FRAMESET> |
<FRAME SRC="footer.html"> |
<NOFRAMES>
|
</NOFRAMES> |
</FRAMESET> |
</HTML> |
A document containing a <FRAMESET> tag must NOT have a <BODY> tag, and so typical HTML tags cannot appear in frameset documents |
One needs a closing </FRAMESET> tag for each <FRAMESET>; no end tag is required for <FRAME> |
A frameset document may contain a <SCRIPT> in its header. The properties and methods in the <SCRIPT> may be accessed by documents inside frames using top.property or top.method |
Anything inside <NOFRAMES> ... </NOFRAMES> will be ignored by a frames-capable browser (such as Netscape 2.0 and above) or processed by a frames-impaired browser (such as Netscape 1.x) |
<HEAD><SCRIPT>...</SCRIPT></HEAD> |
<BODY> |
Various actions that load a new URL into page |
</BODY> |
will result in the loss of all JavaScript methods and properties! |
This can be avoided by using dummy frames: |
<HEAD><SCRIPT>...</SCRIPT></HEAD> |
<FRAMESET ROWS="1,*"> |
<FRAME NAME="DUMMY"> |
<FRAME NAME="ActualFrame"
|
</FRAMESET> |
Now use <a href="URL" target="ActualFrame"> so that reloading will NOT destroy your JavaScript! |
Note we defined a dummy frame above ActualFrame that occupies one pixel (could use zero!). The * notation tells Netscape to assign the remaining rows to the second frame |
<FRAMESET ROWS="rlist" COLS="clist"> ... |
</FRAMESET> |
where rlist and clist are a comma-separated list of values (but typically one of these attributes is omitted and nested framesets are used instead) |
Following <FRAMESET> there must be the correct number of frames defined either by a <FRAME> tag or by a nested <FRAMESET> ... </FRAMESET> |
rlist and clist are a mixture of
|
<FRAME SRC="URL" NAME="name"
|
All of these are optional Ñ the URL is the document to be loaded into this frame, which is often blank since user or script will specify what to load using TARGET="name" in a link |
The value of NAME attribute is used by TARGET and is essential if you want to load a frame from the outside. A document will load into the current frame if no target specified |
scrolling=YES always gives frame scrollbars |
scrolling=NO gives no scrollbars and truncates document if necessary |
scrolling=AUTO allows Netscape to choose if scrollbars are needed |
NORESIZE if present says that user can NOT resize this frame, which has impact on ability of related frames to be resized |
MARGINWIDTH and MARGINHEIGHT are given in pixels to specify the margin to be used around the frame |
There are four major types of events and event handlers:
|
JavaScript introduces new event-handling attributes inside tags that respond to mouse events or keyboard input (in text fields, e.g.) |
One can specify event handlers in two ways, described on the following page |
You can specify event handlers within an HTML tag using attributes such as
|
Recall that JavaScript is case sensitive, but since HTML is case insensitive the onClick keyword may be any mixture of upper and lowercase |
Alternatively, specify event handlers as in
|
The onLoad event handler is automatically called when you load (or reload) a page
|
The onUnload event handler is automatically called when you exit a page |
Images: the onAbort event handler is called when user aborts loading of image (by clicking stop button, e.g.) |
Images and windows: the onError event handler is called when document or image loading causes an error |
Windows, frames, and form elements: the onFocus event handler is called when the mouse moves within the scope of a window, frame, or form input field |
The onBlur handler is the opposite of onFocus |
Checkboxes, buttons (radio, reset, submit) and hyperlinks: the onClick handler is called when the item is clicked |
Select, text, textarea: the onChange handler is called when a change occurs in these fields |
onMouseOver plays same role for links and image maps that onFocus does for form elements |
onMouseOut is the opposite of onMouseover |
Text or textarea: the onSelect handler is called when text is selected |
onSubmit handler is called when the submit button on a form is clicked |
onReset handler is called when the reset button on a form is clicked |
One can define a string of JavaScript as a function object: |
target = new Function( [arg1,...,argn,] functionBody ) |
where the arguments arg1,...,argn are optional |
target is either a variable, a property of an existing object, or an event handler such as window.onerror |
var setBGcolor = |
new Function("document.bgColor='antiquewhite'"); |
You can now execute setBGcolor() but note that the function can be changed at any time. For example, |
setBGcolor = new Function("document.bgColor='pink'"); |
One can define event handlers dynamically, but they MUST be lowercase and they MUST have no arguments:
|
Like eval, the function body may be constructed dynamically:
|
The following example illustrates some simple form elements with onFocus and onClick event handlers: |
<form> |
<input type="text" name="data" size=30 |
onFocus="window.status='this is a test of onFocus'; return true"> |
<input type="submit" value="clickit!" onClick="top.dosomething('This is a test of onClick')"> |
</form> |
window.status is a property holding message at bottom of browser window |
One would typically have onChange handler as well in text field. Note that with these handlers one does NOT necessarily need server-side CGI script to process form |
<a href="" onClick="top.seturl(this,'item27.html')" onMouseOver="window.status='this is a test of onMouseOver'; return true">Exciting Item 27</a> |
This is a very typical use of onClick in a hyperlink |
Keyword this refers to current link object of type location |
Set href to anything, even "", but do not omit otherwise won't be a link Ñ will be an anchor instead! |
Set href and target frame in onClick event handler: |
function seturl(linkname, fileurl) { |
linkname.target = "top.mainframe"; |
linkname.href = fileurl); } |
Put seturl in top frameset document. The <a> link is in a frame where onClick allows seturl to load required document into mainframe, the main display frame |
Top document has JavaScript in <head></head> and defines <frameset></frameset> split in two by columns |
JavaScript has a pair of timeout methods |
// Call setTimeout and assign a handle: |
yourID = setTimeout(exp, msecs); |
// Abort process started by setTimeout: |
clearTimeout(yourID); |
setTimeout starts a timer that causes expression exp to be evaluated after a time interval of msecs milliseconds |
These methods can be used to animate text or images, or make a display change after a given time interval
|
Note setTimeout does not start a loop, just a single timing. Thus clearTimeout need not be called unless abnormal termination is required |
If you want a loop, ensure exp restarts a new setTimeout |
<SCRIPT LANGUAGE="JavaScript"> |
var timerID = null; // setTimeout handle |
var running = false; |
function stopclock() {
|
} |
function startclock() {
|
} |
function showtime() {
|
} |
</SCRIPT> |
The previous script appears in header of document whose body is given by: |
<BODY onLoad="startclock()"> |
<FORM name="clock" onSubmit="0"> |
<input type="text" name="face" size=12 value=""> |
</FORM> |
</BODY> |
Note <FORM> only used for output using
|
onLoad handler starts timer when page is loaded |
The document object has several important subobjects including Anchor, Applet, Area, Form, Image, and Link |
It also has arrays anchors, applets, forms, images, and links holding all occurrences of these objects for a particular document |
We have already illustrated Form and Link; here we look at Image |
The tag <IMG NAME="fred" SRC="jim.gif"> in an HTML file generates an object document.fred of type Image with property document.fred.src="jim.gif" |
One can preload an image using the statement: |
image1 = new Image(); image1.src = "henry.jpg"; |
and then change an image in the document using: |
document.fred.src = image1.src; |
Note the image is fetched from cache, so this is fast! |
This technique can be used for animated images, for example |
There are several issues that are tricky due to asynchronous, thread-based processing in browsers |
This is seen when reloading JavaScript pages, which sometimes produces unclear results since different frames and variables are set in a different order from that in which multi-frame system was built!
|
Note that when you set a location field in a window with a JavaScript command such as: |
window.location = "newurl"; |
subsequent commands are executed immediately and do not wait wait for the new page to be loaded! |
This allows you to dynamically change object definitions |
Consider the function (constructor)
|
Suppose we wanted to add a new property fourwheel
|
We can add methods with
|
We can avoid repainting mycar by assigning
|
Cookies were introduced by Netscape to preserve client state |
For a CGI script servicing several clients (ordering T-shirts perhaps), it is useful for the client (not server) to store information such as name of user, passwords, etc. |
Traditionally, state variable were passed using "hidden" fields:
|
Such hidden fields are passed to CGI scripts in same fashion as other variables set in text fields, etc. |
Hidden values can either by set by JavaScript on the client or embedded into a page constructed by a CGI script, which might read N values and return a new form with M new fields and N old entries preserved in hidden fields |
So hidden variables are nice but only preserved as long as you stick to page you started with or returned by CGI script |
Cookies provide an alternative mechanism where information is saved in a special file on the client called cookies or cookies.txt
|
Such files can preserve information in a more robust way than hidden fields! |
Cookies are supported by Microsoft and Netscape and can be used (like forms) for purely client-side or client-server activities |
Neither hidden fields or cookies are very secure |
Cookies have five attributes: name, expires, domain, path and secure, which are specified on a single line. Only name is required; all other attributes are optional |
name=value; EXPIRES=dateValue; DOMAIN=domainName; PATH=pathName; SECURE |
name is required and gives the name of cookie |
EXPIRES is optional but if present specifies a date after which cookie should be deleted |
EXPIRES uses a modified syntax returned by JavaScript function Dateobject.toGMTString(timevalueinseconds)
|
It appears that one can just use a slightly different syntax of toGMTString:
|
DOMAIN defaults to domain of server where cookie set and suffix matching is performed
|
PATH=/ is most general path and matches all paths; default is path of document that set cookie
|
SECURE if present requires a secure communication channel |
In HTTP header, the brower passes to server any cookies that are valid for a given page |
Note only name=value is passed since PATH, DOMAIN, SECURE, and EXPIRES are used to check if cookie should be passed |
The server stores cookie strings in $HTTP_COOKIE environment variable as name1=value1; name2=value2;
|
One can send cookies back to client using |
Set-cookie: name1=value1; EXPIRES=...; ... |
before the |
content-type: text/html |
header line |
The JavaScript property document.cookie holds cookies that are valid for this document and can be used to either set or retrieve cookie values |
Suppose we have a page with a form that sets values and stores for a certain length of time. This is processed entirely on the client by storing values in appropriate cookie entries |
Cookies may be read on other pages (consistent with PATH and DOMAIN) and if present are used to define JavaScript variables that are used in "parameterized HTML" |
Note document.cookie is set to a single cookie value but when read gives all cookies for this document! |
Tainting ensures that certain properties cannot be freely used |
These "taintable" properties include cookie, links, title, etc in document; most interesting properties of forms; history; location |
Once you access such a property from a SERVER different from that which spawned the JavaScript page, your current statement and everything derived from it is "tainted"
|
Tainted variables may NOT be passed over the network to other servers, e.g., to a CGI Script |
You can control the tainting of pages and untaint them so that remote servers can freely use them
|
LiveConnect is an important but still experimental capability that allows Java applets to freely access JavaScript variables and vice versa |
You can use this to call Java methods in JavaScript noting that a Java package X is called Packages.X in JavaScript |
var mydate = new Packages.java.util.date(); |
Creates a JavaScript variable from the Java Date constructor |
This development potentially gives an interpreted version of Java! |
LiveConnect is only supported by Netscape at present |
You can also change Java variables in running applets as long as they are public (see next page) |
Suppose applet HelloWorld has method:
|
You can change javaslocalcopy from JavaScript using: |
document.applet["HelloWorld"].setString(myStr); |
To avoid a type mismatch, it is best to convert everything explicitly to strings in Java and JavaScript
|
Correspondingly, Java applets can control web pages containing JavaScript functions and thus access capabilities of Netscape Browser explicitly
|
<head> <script language="JavaScript"> |
buttons = new top.MakeArray(2); |
buttons[1] = 'one'; buttons[2] = 'two'; |
function testprocess(obj1, obj2, index) { |
confirm(obj1.name + ' ' +
|
</script> </head> |
Then create a form as follows: |
<form name="testbuttonsform"> |
<script language="JavaScript"> |
top.flexbuttons(1,"testgroup",2,buttons,2,"testprocess"); |
</script> |
</form> |
function flexbuttons(maxradio, groupname, number, indname, indexselected, onprocess) |
/* Output a group of radio buttons or select |
(user responsible for format of <form>): |
- maxradio defines strategy: if more than |
maxradio items use a select field, otherwise |
use radio buttons |
- groupname is name of group |
- number is number of buttons with name |
indname[1..number] |
- indexselected is initial selection running |
from 1 to number |
- onprocess is name of onClick/onChange handler |
*/ |
function flexbuttons(maxradio, groupname, number, indname, indexselected, onprocess) { |
if( number <= maxradio) { // radio buttons
|
} // end if block |
else { // select field
|
} // End else block |
} // End function |