Revised: March 30, 2001

JavaScript

JavaScript is a popular technique used to make web pages dynamic and interactive.  Some of the common uses of JavaScript are the following: 

JavaScript is also used to dynamically change style sheet properties -- this is called DHTML.  A common use of DHTML is animation (moving text or images around the page)

To keep the size of this document down, I have put the code for many of the uses in another document.  For the same reason, I have also put statements which are infrequently used in another document.  For some exercises to work, see a third document.

Procedural Use of JavaScript

JavaScript statements can be used like a traditional programming language, in which each statement is executed in the order it appears on the web page.  JavaScript statements used in a procedural way appear between <SCRIPT> and </SCRIPT> tags.  For example, 

<SCRIPT LANGUAGE="JavaScript">
<!--
var z=3*4
alert (z)
// -->
</SCRIPT>

The alert function brings up a popup box, evaluates what is in parentheses, and displays it.

Comments on code: 

1) Language declaration - There are multiple scripting languages, so even though JavaScript is currently the default, good to specify it.

2) Semicolons - If each statement is on a separate line, semicolons aren't required.  However, if there are errors in your JavaScriipt code, the presence of semicolons in your code may lead to more informative error messages.

3) Comments - Web browsers that support JavaScript execute the JavaScript statements that appear between <SCRIPT></SCRIPT> tags.  Browsers that don't support JavaScript but that recognize the <SCRIPT> tag ignore everything between the <SCRIPT> and </SCRIPT> tags.  However, some old browsers don't even recognize the <SCRIPT> tags and treat all the JavaScript between them as HTML text to be displayed.  The above commenting technique is used so that this last group of old browsers does not display the JavaScript statement as part of the web page.  These browsers recognize the first four characters of the second line above as an HTML comment and the last three characters of line 4 as the end to that comment, and everything is ignored.3 different ways to comment

If you want to add comments to your JavaScript code, you can either use the single line commenting characters // (Any text after // and the end of the line is treated as a comment) or the commenting characters /* and */ (Any text between these characters is treated as a comment; typically used for a multiple-line comment).

Note: If the same JavaScript statements are used in several web pages, one may want to put these in a separate file (with extension .js) rather than putting them between <SCRIPT></SCRIPT> tags in each page.  This reduces file sizes and makes it easier to make changes in the code.  To do this, simply reference the file with the SRC attribute in the <SCRIPT> tag.  The disadvantages are two: (1) The SRC attribute of the <SCRIPT> tag is only supported by browsers that support JavaScript1.1 (level 3 browsers), and (2) the web server hosting the file may need to be configured to use this feature.

Event-Driven Use of JavaScript

Event-driven use of JavaScript is invoked by putting event="string" within an HTML tag where event is an event and string is one or more JavaScript statements separated by semicolons.  There are almost 20 events which are defined in JavaScript and which HTML elements they apply to differs from event to event (see table in Flanagan, p. 285-286).  The most common events that are used are probably onClick, onMouseOut, and onMouseOver.  The name of the event is not case-sensitive.

Core JavaScript 

Core JavaScript is a term used to apply to the elements of the language that are common to both client-side and server-side JavaScript.

Data Types

1) Numbers - In addition to basic arithmetic operators, there are a large number of mathematical functions that are stored as properties of a single Math object, e.g. Math.sin(x) or Math.sqrt(x).

2) Strings - sequence of characters enclosed in single or double quotes.  There are a variety of methods for strings:

parseInt(s) - returns the first number that occurs in s
parseFloat(s) - returns the first number that occurs in s
string.indexOf(substring) - the position of the first occurrence of substring within string.  If no occurrence is found, the value is -1.  Character positions are numbered starting with zero.  string(substring, start) -- the search begins at start.

3) Boolean values - value is true or false

4) Functions - Defined in JavaScript with code like this:

function square(x)
  {
     return x*x
  }

and invoked by using the name of the function, e.g. square(3)

5) Objects  - Collection of named pieces of data; these named values are generally referred to as properties.  To refer to the property, you refer to the object followed by a period and the name of the property.  Functions can be assigned to object properties just like other values can.  When a function is assigned to a property of an object, is is referred to as a method of that object.  For example, you can invoke the write() method of the document object by writing code like this:

document.write("This is a test");

One can also access the properties of an object using associative arrays, i.e.

document["write"]

6) Arrays - Arrays are generally collections of the same type of data.  Thus you could have a string array or an array of numbers.  (JavaScript, unlike most languages, allows you to have an array with some elements strings and other numbers).  Rather than using different variable names for each, elements of an array are referred to by using the array name and the position within the array.  In JavaScript, positions begin with 0, thus a[2] refers to the third element of a.  JavaScript does not support multidimensional arrays, except as arrays of arrays.  Arrays can be created with the Array() constructor function, e.g.

var a = new Array();

You can assign values to the array elements in the above statement, for example var a = new Array ("Sunday", "Monday", "Tuesday") or in subsequent statements.

Operators

Standard operators like +, -, *, /, ^, >, >= , && (logical AND), || (logical OR)along with others such as ** (pre- or post-increment - unary), == (equality), != (not equal to)

Equality (==) -- numbers, strings, and Boolean values compared by value, whereas objects, arrays, and functions are compared by reference; i.e. they are equal only if they refer to the same object

Concatenation operator for strings (+) - e.g. alert ("The answer is " + z);

Conditional operator (?:) - Only ternary operator (three operands) in JavaScript -- the first operator goes before the ?, the second goes between the ? and the :, and the third goes after the :  Value returned by the conditional operator is the value of the second operand if the Boolean value of the first operand is true and the value of the third operand if the Boolean value of the first operand is false.  The same result can be produced, with slightly longer code, by the if statement discussed below. 

The . operator expects an object as its left operand and the name of an object property, including method names, as its right operand.  The right operand should be the literal name of the property or method, without quotes.  It should not be a string or a variable that contains a string.  If the specified property does not exist in the object, JavaScript does not issue an error.

The [] operator allows access to array elements and access to object properties without the restrictions that the . operator places on the right operand.  If the first operand refers to an array, the second operand should be an expression that evaluates to an integer.  If the first operand is a reference to an object, the second operand should be an expression that evaluates to a string that names a property of the object. 

Statements

Compound statements - number of JavaScript statements enclosed with curly brackets; can be used anywhere a single statement is allowed

The if and for statement described below are commonly used commonly.  

if statement -- Multiple forms:

if (expression) statement

if (expression) statement1 else statement 2

for statement

   for (initialize; test, increment)
        statement

  For example, for (count = 0 ; count<10 ; count++)
       document.write(count + "<BR>");

There are other conditional and looping statements which are used occasionally.  

Functions

If you want to do the same thing with JavaScript more than once in a web page and several JavaScript statements are required to perform the action, it generally makes sense to define a function to do this and then call the function from multiple places in the page.  Functions are normally defined between the <HEAD></HEAD> tags for two reasons.  First, putting the statements in the <HEAD></HEAD> means that the code will not be accidentally deleted if one is using an HTML editor in its normal text-editing mode.  Second, JavaScript statements that appear between <SCRIPT> and </SCRIPT> tags are executed in order of appearance as part of the web browser's HTML parsing process.  If a function is defined in the <HEAD> section of the document and called in the <BODY> section, it will be defined when called.  Note that one can define a function (say in the <HEAD> that manipulates objects that are created in the <BODY> section and thus haven't been created yet.  What is required is that the objects exist when the function is called (executed).  One technique is to test for the existence of the object you want to manipulate before you manipulate it.  Note also that the scripts you write and the variables and functions they define do not and cannot persist across web pages.

function funcname(arg1, arg2, ...) {
    statements
   }

A function body requires curly braces, even if the body consists of only a single statement.  The function is not executed when defined, but only when called.  return [ expression ]  is only used in a function body, to specify the value returned by the expression.  The return statement can be used without an expression to simply terminate execution of the function without returning a value.

Arguments object - arguments[] array allows full access to argument values when invoked.  Like all arrays, it has a length property that specifies the number of elements it contains.  Thus you can write functions that accept any number of arguments  for (var i=0; i<arguments.length; i++)

Fundamental Objects in Client-Side JavaScript

In client-side JavaScript, the Window object represent the window (or frame) that displays a document, which is represented by the Document object.  Every window object contains a document property that refers to the Document object associated with the window and a location property that refers to the Location object associated with the window.  

The Windows Object

Pop-up dialog boxes - 3 commonly used Window methods are alert(), confirm(), and prompt().  You can use the newline character "/n" in each, but other than that, formatting is limited.  All 3 methods display a message to the user -- that is all alert() does. 
confirm() - If the user clicks the OK button, confirm() returns true; if the user clicks Cancel, it returns false
prompt(message, default) - for default, you pass the empty string ("") to make prompt() display an empty input box; prompt returns what the user types in the box.  For either confirm or prompt, you can store the value that is returned by using the method in an assignment statement, e.g. a=prompt("How are you doing","") will assign to a whatever the user types in the box

Status line - You can change what text appears in the status line using the status and defaultStatus properties of the Window object.  Normally when a page is displayed in a browser, nothing is displayed in the status line at the bottom of the browser unless the mouse is over a link or a browser control button.  If you want to display a message at the times when no message would normally be displayed, you use the defaultStatus property.  For example, 

<SCRIPT> 
defaultStatus = "Welcome! Click on underlined blue text to navigate.";
</SCRIPT>

Alternatively, you can display a message when a particular event occurs.  For example, when the mouse is over a link, the URL of the link is normally displayed.  You can replace this by another message by adding to the link tag the following:

onMouseOver="status='Go to Site Map'; return true;"  

It is necessary to include the return true statement to prevent the default action (in this case, displaying the URL).

Timeouts and Intervals

setTimeout(code,delay) where code is a string that contains the JavaScript code to be executed after the delay (expressed in milliseconds) has elapsed.  Note that the statements in code are executed only once.  To execute code repeatedly, code must itself contain a call to setTimeout().

clearTimeout(timeoutId) where timeoutId is a value returned by setTimeout() that identifies the timeout to be cancelled.

In JavaScript 1.2, you can use setInterval(code, interval) and clearInterval -- these automatically schedule the code to run repeatedly, and so there is no need for the code to call setTimeout

These methods can be used to animate the status line although this can become distracting if it changes too often.

Screen Object (JavaScript 1.2) - width and height specify the size of the display in pixels, where availWidth and availHeight properties specify the display size that is actually available -- you can use these properties to help  decide what size images to include in a document; colorDepth property specifies the base-2 logarithm of the number of colors that can be displayed.

Window Control Methods

window.open(URL of document to be displayed in new window, name of window, list of features that specify the window size and GUI decorations, boolean value for existing windows specifying whether the URL specified as the first argument should replace the current entry in the window's browsing history).  For example, to open a small resizeable browser window with a status bar but no menubar, toolbar, or location bar, you could use the following line of JavaScript:

var w = window.open("smallwin.html", "smallwin", "width=400,height=350,status=yes,resizable=yes");

In the third argument, any features you do not explicitly mention are omitted.  Height and width can only be specified in absolute terms (pixels), however I would think one could use the the width and height properties of the Screen object discussed above to scale the new window depending on the resolution of the user's display.  Spaces in the third argument seemed to cause a problem in Netscape.

One can also control where the popup window appears in level 4 and later browsers.  However, the properties to do so differ between Netscape and Internet Explorer.  One could use the browser detection JavaScript properties and methods discussed above to write code that would work for both browsers. 

window.close

Location Object

location="newpage.html";  will load newpage.html into the browser

History Object

back() and forward() methods

Multiple Windows and Frames

window.frames[0] - first frame
window.frames[1].frames[2] -- third subframe of second frame

One refers to a sibling frame by use of parent.  For example, from the first frame, you can refer to a variable i in  the second frame (a sibling frame) by writing: parent.frames[1].i

If you name a frame in the HTML with the NAME attribute, you can then use that name to refer to the frame.  For example you can write

parent.table_of_contents rather than parent.frames[1] if the second frame has been given the name table_of_contents.

The Document Object

The Document Object Model specifies how a scripting language can access and manipulate the detailed structure of an HTML document.  The color properties of the Document object are read/write properties, but they can only be set before the <BODY> tag is parsed;  the exception to this rule is the bgColor property, which can be set at any time.

lastModified - a string that contains the modification date of the document

The code to do this is

document.write("This document was last modified on " + lastModified);

referrer - the URL of the document that contained the link that the user clicked on.  If you save this value as a hidden field of a form on your website, you can save this data on the server and hence analyze the links that refer to your page.  To test this, I have linked to a page which contains the following JavaScript: document.write(document.referrer).  In Internet Explorer 5.0, this feature worked after files had been transferred to the server, but did not work when the page was tested locally on my computer.  (The referrer property is blank if the referring site is a secure site but no lock appears in the browser when viewing a local site, so this may not explain this).

write() - if you call write() from an event handler, you will end up overwriting the current document so using write from an event handler is not recommended.  However, you can write to a document in another window or frame.
writeln() - identical except that it appends a new line

images[] - added in JavaScript 1.1 - the main feature is that the src property is read/write.  You can set the src property to make the browser load and display a new image in the same space -- new image must be same height and width as the original one.  To make the image replacement technique viable, the necessary images must be pre-loaded into the browser's cache.  To do this, you create an off-screen image and load the desired image into it

image1 = new Image();    // first you create an image object with the image constructor
image1.src = cowon.gif       // Tell it what URL to load

To perform image replacement with an off-screen Image object, you do not assign the Image object directly into the images[] array of the Document object.  Instead you simply set the src property of the desired on-screen image to the URL of the desired image.

forms[] array - the forms object has an elements[] property.

Forms are created by static HTML elements -- the exception is the Option object.  

forms[0] refers to the first form in a document

forms[1].elements[2] refers to the third element of the second form in the document of the current window

submit() and reset() methods and the onSubmit and onReset event handlers -- if the latter return false, the submission or resetting doesn't occur

The important event handlers for most form elements are either onClick (buttons, checkboxes, radio buttons, and other buttons) and onChange (text, textarea, and select).

As of JavaScript 1.1, every form element object has a type property that identifies what type of element it is.  Every form element also has a form property, so you can refer to other forms as well as the current form.

Naming Forms and Form Elements - The <FORM> attribute has a name you can set, and you can refer to this name in JavaScript rather than using array notation.  The other HTML tags that have NAME attributes (such as IMG) work the same way.  In addition, all the elements of a form have name attributes, so you can carry the naming one level down.  Since grouped Radio buttons all have the same name, JavaScript places those elements into an array.

Form Element Values - The value property works differently, depending on the type of form element, in accord with the value attribute in HTML.

Select and Option objects - As of JavaScript 1.1, the option objects can be created dynamically at runtime so the contents of one drop down list can be modified by the user selection on another drop down list.

Navigator Object 

The Navigator object is a child of the document object.  The following 4 properties of the Navigator object are commonly used in browser-detection JavaScript:

appName - the name of the web browser (e.g. Netscape or Microsoft Internet Explorer)
appVersion - platform and version information - what information is returned depends on the browser, but both Netscape and IE return a version number as the first part. This means you can pass this property to parseInt() or to parseFloat().
userAgent - typically this is the value of appCodeName followed by a slash and the value of appVersion
appCodeName - the code name for the browser ("Mozilla for Netscape 2-4 and IE 4)

For example:

var Netscape = false;
var IE=false;
if (navigator.appName.indexOf("Netscape") != -1) Netscape = true;
  else if (navigator.appName.indexOf("Microsoft") != -1) IE = true; 

Compatibility Techniques

There are a variety of approaches:

Platform and Browser Compatibility

Least Common Denominator - you only use features that are known to work on all your target platforms

Defensive coding - Test for the existence of a method --e.g., if (s.split) // if method exists, use it
else   // use our alternative implementation

Platform specific workarounds -

Use server-side scripts to test what browser the user is running and therefore serve up the appropriate JavaScript

Ignore the problem

Inform the user that the features aren't available

How do we use new features of JavaScript without causing errors in browsers that do not support these

1) LANGUAGE attribute - specifying JavaScript 1.2 causes some problems with Navigator so is best avoided

Setting version variables

<script LANGUAGE="JavaScript"> var _version = 1.0; </script>
<script LANGUAGE="JavaScript1.1">  _version = 1.1; </script>
<script LANGUAGE="JavaScript1.2">  _version = 1.2; </script>

You can then test for version 1.2 code without having to specify it in the LANGUAGE attribute

2) Loading a new page using the Location.replace() method after you have tested for support of a JavaScript language version.  

3) Hiding scripts from old browsers

<SCRIPT LANGUAGE="JavaScript">
<!--
   JavaScript statements
// -->
</SCRIPT>

<NOSCRIPT> </NOSCRIPT> tags enclose an arbitrary block of HTML text that should be displayed by any browser that does not support JavaScript.  For example, you could display a message that the browser cannot correctly display your pages that require JavaScript.  However, the <NOSCRIPT> tag is not supported in Navigator 2, it ignores the tags and displays the intervening text, even though Navigator 2 supports JavaScript.


This entire writeup draws heavily from JavaScript The Definitive Guide by David Flanagan, Third Edition, 1998.  Comments to William Pegram, wpegram@nvcc.edu