Chapter 4 Reading and Manipulating Text Strings

Javascript Guide

by Stephen Wilson (c) 1996

Note: These draft javascript tutorials are presented for the personal use of students in the Conceptual Design Department at San Francisco State University and for members of the Internet community. It is not permitted to creproduce sell, or redistribute without permission of Stephen Wilson. swilson@sfsu.edu

What are String Objects and Their Properties?

String object is an elaborate name for a grouping of text. The text can be a name, a phrase, a sentence, or even paragraphs or longer. It is called a string because it is a string of letters. Strings can be either "literals" or variables. A literal string means text that you place in quotations marks. This tells Javascript to accept it as is without trying to evaluate it further. Several earlier examples have used string literals.

For example, the first sample would put the words "This should....field" into the text input field named "inputfield1" in a form. The second sample would generate an alert box for the user that printed "Are you sure?"

document.myform.inputfield1.value = "This should appear in the field"

alert("Are you sure?")

As with most Javascript objects you can read and set the characteristics of any string object. You can also apply methods to themto change their characteristics. To apply methods to string objects, you usually first assign the text to a variable. Then you can manipulate the text by manipulating the variable. The following example creates a string called mytext. It then reads the length of the sting and prints it out in an alert box.

1. mytext = "This is a sample."

2. len = mytext.length()&&

3. alert("The string is " + len + "characters long.")

(would print alert box cotaining "The string is 17 characters long.")

Line 1 creates a variable containing the sentence. Line 2 uses the dot notation syntax (.length) to get the length of the sentence and assigns its value to the variable arbitraily named len. Line 3 generates an alert box. It creates a compound sentence by combining the literal string "The string is " with the variable len and the literal "characteris long". The Javascript syntax to combines strings uses the plus (+) sign. Length includes all spaces and punctuations. The sample string is 17 characters long.

A variety of methods can be applied to strings to change characterists such as color, size, and style. Scripts can also manipulate and analyze sturctural features such as changing identity as an HTML link or anchor and extracting substrings.

Example 4.1 shows simple construction of strings with designated visual characteristics. It assigns the string "What is all this?" to a variable arbitraily named test. It then opens a document to contain the text that is generated by applying the open() method to a document object. It then uses the write method to output the text. Each line contains the string variable with a different appearance method applied. For example, doucument.write(test.bold()) outputs the variable test (the words "What is all this?") in bold. The line document.write(test.fontsize(7)) outputs the words in characters corresponding to Navigator's size 7. All methods require the syntax of parentheses following their name. Some methods require parentheses which contain parameters related to the methods action .fontcolor("red") and others can be empty such as .bold(). This example adds the characters"<P>" at the end of each string it prints out in order to add a return character at the end; otherwise, each set of words would appear right next to previous words. (&& explain why the writeln does not work.) These methods could be applied directly to a literat text rather than a variable although it is usually more convenient to work with variables. For example, the line document.write("Raw text".bold()) would out the words in bold.

<SCRIPT> //assigns value to variable test ="What is all this?" // opens document and uses methods to modify text characteristics document.open() document.write(test.bold()+"<P>") document.write(test.fontsize(7)+"<P>") document.write(test.fontcolor("red")+"<P>") document.write(test.toUpperCase()+"<P>") //assigns multiple characteristics to text document.write(test.italics().fontsize(6).fontcolor("green")+"<P>") document.open() </SCRIPT>

Table 4.1 briefly reviews all the methods that can be applied to strings. All the methods that rely on knowing character positions in a string use the convention of considering the first character as position 0, not 1. For example, the charAt(n) method would indicate that the second letter in a word is at position 1.

Table 4.1

Summary of Methods to be Applied to Strings

Method

Syntax & samples
Effect
Appearance


big(), small()
q = sent.small()

document.write(sent.big())

Similar to applying Navigator's <big> and <small> tags. Changes size of font relative to current size.&&
bold(), fixed(), italics(), strike(), sub(), sup(), blink()
q = sent.bold()

document.write(sent.italics())

Similar to applying HTML tags to control style such as <B>q</B>. No parameter required inside parenthesis.

Fixed means fixed letter size font like a typewriter

sub means supscript and sup means superscirpt.

Strike means strikethrough as in legal text.

fontsize()
q = sent.fontsize(6)
Similar to applying Navigator's fontsize tags. Values can range from 1 to 7
fontcolor()
q = sent.fontcolor("red")&&
Changes the color of text. Color values must be special hexadecimal notation (54FF3A) or drawn from the array of color names defined by Javascrfipt. See appendix &&
toLowerCase(),

to UpperCase()

q = sent.toLowerCase()
Converts the text to be all lower or upper case letters.
Structural


length
q = sent.length
Returns the length of the string.
anchor(), link()&&
q = sent.anchor()

document.write(sent.link())&&

Link() encloses text in HTML tags to make it a appear as link. Anchor() makes it appea&&r as anchor associated wtih link.
charAt()
q = sent.charAt(3)
Returns the character at a particular position in string. If sent = "apples" then charAt(3) would be "l". (**All strings are assumed to start with position 0 so a is 0, p is 1, etc.)
subString(a,b)
q = sent.subString(2,4)
Returns the characters between two positions in a string starting with beginning and ending on character before the last index. If sent = "apples" then subString(2,4) would be "pl".
indexOf(a)

indextOf(a,n)

q = sent.indexOf("l")

q = sent.indexOf("l",2)

Returns a character's or string's position in a parent string. If sent = "apples" the indexOf("l") would be 3.

The search starts at 0 unless you specify a fromIndex starting point in optional second parameter.

lastIndexOf(a)

lastIndexOf(a,n)

q = sent.lastindexOf("l")

q = sent.lastindexOf("l",4)

Returns the position of the last occurence of a character's or string. If sent = "apples" the lastIndexOf("p") would be 2.

The search starts at the end unless you specify a fromIndex starting point in optional second parameter.

String visual characteristics can only be controlled when the text is a part of a document that appears in a window. For example the style and color methods will not change the visual characteristics text that appears in text field areas in forms, in alert boxes, or in the status bar at the bottom of the screen.

Using Javascript to Change and Compose Text

Javascript affords you powerful opportunties to dynamically change and compose text. For example, the substring(n1,n2) allows easy access to parts of longer strings. Using the sample variable test (What is all this?) from above, document.write(test.subString(5,13)) would return the words "is all". Since subString(a,b) counts the first character as character 0, the "i" is character 5. The second index number 13 indicates the character before which to stop. The space after the word "all" is character 13 so subString(5,13) would generate the words indicated.(&& test this). Remember all punctuation marks and spaces count as characters.

The method charAt() will return the character at a particular location (counting the first character as 0). Thus, test.charAt(5) should return the letter "a". Related methods of indexOf() and lastIndexOf() execute the reverse process. Feed them a test string and they indicate the location where you can find it either starting from the front (indexOf()) or from the back (lastIndexOf()). Test.indexOf("a") would return 2 because the "a" that is part of "What" is in position 2. Test.lastIndexOf("a") would return 8 because the first "a" from the back is the "a" of the word "all". IndexOf() and lastIndexOf() allow specification of a second optional parameter that can tell Javascript to start somewhere other than the beginning or the end. If we had specified test.indexOf("a",4) would return 8 because it would start searching at position 4 and would thus find the "a" of the word "all" rather than the "a" of the word "What" which occurs before its starting points. This ability to create complex text and move around in them can be very useful.&&

Using Substrings to Generate Scrolling Banners

Example 4.2 uses the subString method to create a scrolling banner in a text field. Scrolling text seems to slide from left to right. You can create this effect by systematically displaying a changing section of some target text. For example, if you display character 0 to 24 of some text and next display 1 to 25 and next 2 to 26, the text will appear to be moving from right to left. The sample illustrates a method for accomplishing this effect.

<HTML> <HEAD><TITLE> Banner</TITLE> <SCRIPT LANGUAGE= "javascript"> // Puts the text to scroll into variable called sent - SECTION A // uses length propert to assess its length and put into variable slen // initalizes a,b,n, and subsent variables var sent = "This is a demonstration of a banner moving from the left to right. It makes use of the substring property of Javascript to make an interesting display" var slen = sent.length var siz = 25 var a = -3, b = 0 var subsent = "x" // Creates a function to capture substrings of sent - SECTION B function makeSub(a,b) { subsent = sent.substring(a,b) ; return subsent; } //Creates a function that increments the indexes of the substring - SECTION C //each time and calls the makeSub() function to geneate strings //a indicates start of substring and siz indicates size of string required function newMake() { a = a + 3; b = a + siz makeSub(a,b); return subsent } //function uses loop to get changing substrings of target - SECTION D //repeatedly calls newMake to get next substring //uses setTimeout() command to arrange for substrings to display // at specified times function doIt() { for (var i = 1; i <= slen ; i++) { setTimeout("document.z.textdisplay.value = newMake()", i*300); setTimeout("window.status = newMake()", i*300); } } </SCRIPT> </HEAD> <BODY > <HR> <CENTER> <FORM NAME="z"> <INPUT NAME="textdisplay" TYPE="text" SIZE=25> <P> <INPUT NAME="doit" Type="button" value = "Run Banner" onClick = "doIt()"> </FORM></CENTER> <HR> </BODY></HTML>

Section A creates a variable called sent to contain the sentence to be scrolled. You could enter whatever you wanted. It uses the var statement which is Javascript's way of creating a global variable that will be available to all sections of the script. The syntax is the word var followed by space, followed by the name of the variable, optionally followed by the equal sign (=), and the value to be initialized to. Using the length property, it determines the length of the string you have entered and assigns it to a variable called slen. It creates the variable siz and assigns the value 25 to it. This is the length of segment that will appear to scroll. You could make it whatever size you want, but it should be coordinated with the size of the text field it which it will appear. It creates and initializes variables a,b, and subsent that various functions will use.

<sidebar&& First look at var>

Section B is a function whose job is to determine a substring of the target text. It uses the method subString() applied to the string variable sent (subsent = sent.subString(a,b). The indexes a and b will be systematically incremented by another function in order to produce the effect of scrolling text. The function returns subsent, the substring that it has extracted.

<&&sidebar?>

A First Look at Functions

&& first time for tuncitons. Since this is the first function seen in these samples, a brief explanation is called for. More details will be presented in chapter &&. Functions are very useful subroutines. They are sets of commands and Javascript structures that a script might repeatedly call. Since you can vary the parameters you send to them they can be very flexible.

The syntax for creating functions calls for the word function , followed by the name you arbitraililly give to it, immediately followed by parentheses that enclose parameters sent to the function, followed by an opening bracket. ({), The parentheses must be used even if there are no parameters and there cannot be any space between the function name and them. The next lines contain the commands each ended with a semicolon. The last line often contains the command return followed by the values that the function has generated. A final line contains the closing bracket.

function funcname(a,b) {

statement 1;

statement 2;

}

<end sidebar>

Section C creates a function called newMake that systematically increments the starting point (a) of the substring and ending point (b). b is calculated by adding the variable siz to a each time. Siz is the variable indicated at the beginning for the number of characters to compose the banner. This function increments the string by 3 characters each time (a+3). The 3 controls how fast the text seems to scroll. The value 1 makes text scroll slowly. Higher values would make it seem to go faster although too big of values results in choppy jumps that can be hard to follow. The function calculates a and b and then calls the makeSub function to get the substring with the new starting and ending points.

Section D sets up a function called doIt that creates the set of substrings that will make up the scrolling banner. It uses a for loop structure to repeatedly call the newMake function. This for loop sets up a counter (i), starts by setting it equal to a given value (1), executes the commands inside the loop, adds 1 to the counter, checks if the counter is now past the limit (in this situation slen, the length of the target text) and then repeats until it is.

The function uses the set TimeOut command to cause each substring to appear at a increasingly delayed time. It uses the counter (i) to calculate the time the substring will appear. The second parameter in the setTimeOut() function indicates the number of milliseconds to wait before realizing the action indicated in the first parameter. The values of the second parameter will assume multiples of 300 - 300,600,900, etc. The banner will thus scroll every three tenths of a second. Setting that multiple to lower or higher values could change how often the scroll happens. The first parameter is a call to the newMake function to generate a new substring. Thus the loop sets up a series of appearance events with incremental parts of the string showing every three tenths of a second.

To illustrate options, the sample causes the banner to appear in two places. The first line puts the string into the text field called textdisplay inside the form called z by setting the value property. (document.z.textdisplay.value=). The second line uses Javascript's ability to set the text in the status bar at the bottom of the window (window.status=). Status is a property of the window object. Window objects are discussed in chapter &&.

<&&sidebar?>

A First Look at For Loops

Most computer languages include structures to repeat actions in systematic ways. Chapter && describes the variety of loops available in Javascript. Here is the basic syntax of the for loop.

for (var counter = start; counter < limit; change pattern) {

statement 1:

statement 2;

}

Javascript's for loop structure requires three values to be specfied. These values are enclosed in parentheses and separated by semicolons:

1. You must set up a counter that will keep track of where the loop is and indicate its starting value. In example 4.2 the counter is named i and set to the value of 1.

2. You must set up a test condition that will determine when the loop is done. Typically, these tests assess whether the counter has reached some limit. Example 4.2 tests whether i is still less than or equal to the length of the target text(<= slen).

3. You must arrange for the counter to have its values change. It can be incremented or decremented. Example 4.2 adds 1 to i each time through the loop. Javascript uses the common convention of the double plus signs to indicate increment by 1 (i++).

For loops then use the open bracket to enclose the commands and structures that will be executed by each iteration of the loop. Each statement is terminated with a semicolon. The loop is concluded with a close bracket.

<end sidebar>

How to Use Javascript to Create Links and Anchor

s>

Hypermedia is at the heart of the Web. Often you will want your interactive Web pages to generate new Web pages in response to user actions. You may want to include dynamically generated HTML links as part of these pages. Javascript makes it easy to format text as links and anchors. Once formatted, they can function as pages of live links.

Javascript uses the link() and anchor() methods to transform text into properly formatted HTML code. Anchors are pointers inside of a document that can be accessed by internal and external references. The standard HTML code for an anchor is:

<A NAME="animal1"> Elephants</A>

The phrase "animal1" would not be seen by the viewer of the page. It would function, however, as a target for links. For example the link <A HREF="#animal1"> some place elsewhere in the document would take the user to this place in the text. The word Elephants would be text the user would see that would be positioned at the top of the viewer's window. Javascript would create the link above by using this notation. Nothing would appear in a window until the document.open() and document.write() methods were applied.

var tx = "Elephants";

document.writeln(tx.anchor("animal1");

You could also create text formatted as a link using the link() method. The standard HTML notation for a link is:

<A HREF = "http://netaddress/filename.html"> Important Information </A>

Javascript allows scripts to dynamically construct links in a fashion to the way it constructs anchors. The script needs only to apply the links() method to the text to serve as the link gateway. The URL to be linked to is placed inside the parenthesis. Javascript will then generate an appropriately formatted HTML link. For the example above the syntax would be:

var gate = "Important Information";

document.writeln(gate.link("http://netaddress/filename.html");

Example 4.3 shows a script that would dynamically generate a page of links based on choices that the user makes. The page asks the user to indicate a country of interest and responds with links to resources in that country. The script creates the arrays of gateway text and links and differentially displays them depending on which radio button the user has selected.

<HTML> <HEAD><TITLE>Links for Various Countries</TITLE> <SCRIPT LANGUAGE= "Javascript"> // function to create and initialize arrays -- SECTION A // requires length as argument // initialize other variables function makeArray(n) { this.length = n; for (var i = 1; i <= n; i++) { this[i] = 0 } return this } var targetgates = new makeArray(3) var targetlinks = new makeArray(3) var coun = "z" var arlen = 0 var n = 0 // initialize arrays to hold each country's links-- SECTION B // assign values to members of the array. Starts with 3 // gates are the text gateways that will appear in window // links are the URLs that each gateway leads to // more can be added at any time var japangates = new makeArray(3); var japanlinks = new makeArray(3); japangates[1] = "Japanese Music" japangates[2] = "Japanese Art" japangates[3] = "Japanese Politics"; japanlinks[1] = "http://netad.jp/mus.html"; japanlinks[2] = "http://netad.jp/art.html"; japanlinks[3] = "http://netad.jp/pol.html"; var indiagates = new makeArray(3) var indialinks = new makeArray(3) indiagates[1] = "Indian Music" indiagates[2] = "Indian Art" indiagates[3] = "Indian Politics" indialinks[1] = "http://netad.in/mus.html" indialinks[2] = "http://netad.in/art.html" indialinks[3] = "http://netad.in/pol.html" var chinagates = new makeArray(3) var chinalinks = new makeArray(3) chinagates[1] = "Chinese Music" chinagates[2] = "Chinese Art" chinagates[3] = "Chinese Politics" chinalinks[1] = "http://netad.cn/mus.html" chinalinks[2] = "http://netad.cn/art.html" chinalinks[3] = "http://netad.cn/pol.html" // master function to execute process -- SECTION C function doIt() { getValues(); displayIt(); } // function to fill targetgateways and targetlinks arrays -- SECTION D // these arrays are filled with the values from appropriate country // based on user clicks of radio buttons // for loop is used to assign each corresponding member of country // arrays to appropriate member of target arrays function getValues() { if (coun == "japan") { arlen = japanlinks[0] + 1 for (var i = 0; i < arlen; i++ ) { targetgates[i] = japangates[i] targetlinks [i] = japanlinks[i] } } if (coun == "india") { arlen = indialinks[0] + 1 for (var i = 0; i < arlen; i++ ) { targetgates[i] = indiagates[i] targetlinks [i] = indialinks[i] } } if (coun == "china") { arlen = chinalinks[0] + 1 for (var i = 0; i < arlen; i++ ) { targetgates[i] = chinagates[i] targetlinks [i] = chinalinks[i] } } } // function to actually build page from appropriate links-- SECTION E // creates a new window called diswin function displayIt() { diswin = window.open(); diswin.document.open(); diswin.document.writeln("<H3>Here are links from "+ coun.toUpperCase() +"<P>"); arlen = targetlinks[0] + 1 <P> for ( var i = 1; i < arlen; i++ ) { diswin.document.writeln(targetgates[i].link(targetlinks[i])); diswin.document.writeln("<P>"); } diswin.document.writeln("</H3>"); diswin.document.close(); } </SCRIPT> <P> </HEAD> <BODY > <HR> <DL> <DT> <H3> Access to Information about Japan, China, and India <DD>Please pick the country that interests you.<p></H3></DL> <HR> <FORM NAME="cc"> <INPUT NAME="which" TYPE="radio" VALUE = "japan" onClick="coun= 'japan'"> Japan <P> <INPUT NAME="which" TYPE="radio" VALUE = "india" onClick="coun = 'india'"> India <P> <INPUT NAME="which" TYPE="radio" VALUE = "china" onClick="coun = 'china'"> China<P> <CENTER> <INPUT NAME="bu" TYPE="button" VALUE = "Fetch me links" onClick="doIt()"> </FORM></CENTER> <HR> <SCRIPT> // set up defaults -- SECTION F var coun = "japan" document.cc.which[0].checked = true document.cc.which[1].checked = false document.cc.which[2].checked = false </SCRIPT> </BODY> </HTML>

<

Section A of the script sets up the basic function to create an array (makeArray. Remember Javascript requires an initialization and specification of size before the array is used. MakeArray requires a parameter indicating the length of the array. Using the javascript structure of this, it then uses a for loop to create each member with a starting value 0. This can be used self referentially to indicate methods and properties should be associated with itself (this[n] = 0). The remainder of the section creates and intializes the targetgateways and targetlinks arrays and other variables. The other ways that arrays can be created are discussed in chapter &&.

Section B creates the arrays that will hold the links and gateway text for each country. For example, it creates the arrays japangates and japanlinks and allocates 3 spaces to start with. You could easily change these values by substituting other numbers and inputing the links and text that would fill each position. (Do not use the var indicator in front of the individual members. This would indicate that they are different than the array already initialized&&). This section creates 3 entries for Japan,India, and China. The links must be valid URLs; Those used in the example are just templates for what you would enter.

Section C creates a simple doIt function which calls all the other functions in the right order. It is the function that is called when the user clicks on the fetch button.

Section D creates a getValues function, which fills the arrays targetlinks and targetgates with the values that relate to the user's choice of countries. It uses a series of if statements to test which value the variable coun holds. The radio buttons on the form each assign coun a different value for the country they represent. For example, if the user selects "Japan" then coun assumes the value "japan" and this function will fill the arrays targetlinks and targetgates with values from the japan arrays. Each if statement uses a for loop to sequentially fill each member of the arrays.

Section E creates the displayIt function which creates a new window full of the appropriate links. It opens a window called diswin with the open() method, opens a document with the open() method, and uses the writeln method to output the appropriate text. It includes HTML tags <H3> to set up the text size and <P> tags to force new lines. (&& why doesnt writeln work). A for loop at its heart moves through the arrays targetlinks and targetgates constructing each line of the links. The basic pattern for using the link() method is

writeln(gatewaytext.link(URL))

Gateway text means the phrase the user sees that becomes the active link to the URL specified. Example 4.3 looks more complicated because the gateway text and URL are retrieved from the arrays. The statement prior to the loop assigns the length of the array to the variable arlen. In Javascript the 0 element of an array holds its length; thus targetlinks[0] returns a 3. The for loop starts at 1 . The test condition checks for the counter i being less than arlen+ 1. It should keep retrieving values as long as it does not go beyond the end of the array. The counter i is incremented by one each time (i++) through the loop.

The links() methods formats the retrieved text to be an valid HTML link. For example the first item to be written out would be targetgateways[1].links(targetlinks[1]). If the selected country were Japan, this would translate to "Japanese music".links("http://netad.jp/mus.html"). The writeln() method is applied to this text to send it out to the window. Javascript would actually send the following to the browser, which displays it like a normal link.

<A HREF = " http://netad.jp/mus.html">Japanese Music"</A>

To actually write it out the script must apply the writeln mehtod to the window object (named diswin here) and its document (diswin.document.writeln(text)). Finally Javascript requres the close method to be applied to the document in order for the window to be displayed.

Section F sets up defaults so that a user cannot try to fetch anything before a value was set by clicking on the radio buttons. It sets the default value of coun to be "japan" and the radio button for Japan to be selected.

In the form on the page each radio button includes an onClick handler. Each handler sets coun to be equal to the country the button represents. Coun is the critical variable that determines which array of links gets loaded in. The Fetch me the links button includes an onClick handler that activates the doIt() function when clicked.

to suggest pages for inclusion

Aesthetics of Text Display

Javascript gives Web designers new capabilities for displaying text. New responsiblities come with that new power. When should text be animated and when still? Where should text be displayed? How often should the animations occur? How many letters should advance in each animation? How can the animation be linked with communication goals?

&& needs more maybe at end of chapter?

&& aesthetics

&& in status bar, faster or slower.

<HTML> <HEAD><TITLE> Random Setences ala Yeats</TITLE> <SCRIPT LANGUAGE= "javascript"> function makeArray() { this.length = makeArray.arguments.length for (var i = 0; i < this.length; i++) this[i+1] = makeArray.arguments[i] } var ad = new makeArray( "sensual","old","young","dying","all") var ve = new makeArray( "commend","beget","catch","neglect") var no = new makeArray("countries","men","arms","trees","generations","songs") var col = new makeArray("red","green","blue","black") function fakerand(lim) { var now = new Date() var seconds = now.getSeconds() temprand = ((seconds/60)*lim)+1 rand = Math.round(temprand) } function fakerand1(lim){ var now1 = new Date() var seconds = now1.getSeconds() rand1 = Math.round(Math.abs(Math.sin(seconds))*lim) } function applyEffects() { diswin = window.open() diswin.document.open(); fakerand(4) fc = col[rand] fakerand1(4) fs = rand1+2 sent2=sent.bold() diswin.document.write(sent2.fontcolor(fc).fontsize(fs)); var explain = "<P>This was color "+fc+" and size "+fs; diswin.document.writeln(explain) diswin.document.close() } function maketext() { fakerand(6) adj = ad[rand] fakerand(4) ver = ve[rand] fakerand(5) nou = no[rand] fakerand1(5) nou1 = no[rand1] fakerand1(6) adj1 = ad[rand1] sent = adj+" "+nou+" "+ver+" "+adj1+" "+nou1 } function doIt() { maketext(); applyEffects(); for (var i = 1; i < 8000; i++) { } diswin.close() } </SCRIPT> </HEAD> <BODY > <HR> <CENTER> <FORM NAME="bb"> <INPUT NAME="bu" TYPE="button" VALUE = "See a sentence in language of Yeats" onClick="doIt()"> </FORM></CENTER> <HR> </BODY> </HTML>

move blink through a status bar

- This page created by Stephen Wilson, Professor Conceptual Design, SFSU (http://userwww.sfsu.edu/~swilson) swilson@sfsu.edu
- More information about the Conceptual Design program is available at (http://userwww.sfsu.edu/~infoarts)
- It is a resource used in Art511 Art&Telecommunications course (http://userwww.sfsu.edu/~infoarts/Tele/Tele95.index.html)
- A comprehensive guide to Web design is available in the book World Wide Web Design Guide (Hayden Books) by Stephen Wilson
- The url of this page is (http://userwww.sfsu.edu/~infoarts/Tele/wilson.javascript4r.html)