In this lesson we will learn to write scripts for webpages that are event driven, meaning that the script only executes when some event occurs. In this kind of script document.write(...) isn't useful, because there is no "current location" like there is when scripts execute as part of the browser reading and processing an HTML document. Thus, these scripts need to make use of new DOM facilities like document.getElementById(...) to make changes at given locations.

Some vocabulary, and naming parts of your HTML document

What comes next is scripts that are event-driven, meaning that the scripts execute in response to some event, like a user clicking on something, and not simply as part of loading the page. In preparation for that, we need to make sure we understand some vocabulary, and that we know a bit more about the DOM.
  1. element — anything wrapped between start and end tags in an HTML document is called an element of the HTML document. (Note that elements like img and br don't require end tags.) The type of the element is determined by the name of the tag.
  2. attribute — elements may have attributes that further refine what they are. Attributes are normally defined within the element's opening tag with the name=value syntax. For example, the img element almost always has the src attribute set ... set to the URL/path for the image you're showing.
You should be able to, for example, annotate a chunk of HTML like this:
                     ____ start tag _________
                    /                        \              end tag
                   /       _attribute value_ | __innerHTML_  __|
                  /       /                 \|/            \/  \
I like to shop at <a href="">Joe's Hardware</a> in Joesville.
                  |  \__/- attribute name                      |
                  \  |_______________________/                 /
                   \         attribute                        /
Even though we've made very little use of attributes so far, there are a lot of things you can do with them. For instance, you can give a name to any element you like by setting its id attribute. For example, the following line defines two "b" elements, one give the id foo and the other given the id bar.
Here we have a <b id="foo">"b" element named foo</b> and here we have a <b id="bar">"b" element named bar</b>.
The cool thing about naming elements is that you can refer to them inside Javascripts by name with the document.getElementById(...) function, like this:
The object within your program that's returned by this function can be manipulated in many ways. Every element has a Javascript-accessible value called .innerHTML, which stores whatever is between the start and end tags of the element as a string. Every element also has a Javascript-accessible object called .style that itself contains values (of type string) for the many, many properties that affect the way an element looks in the browser. In the example below, we look at a few of these values: color (the color of the text), background (the element's background color) fontFamily (monospace, cursive, serif, etc), fontSize (the font size, of course), etc.
(look here) ← These parens are defined by this code: (<b id="tryme">look here</b>)
Enter some expressions into the interpreter to the right that manipulate the b/id=tryme element. Here are some good ones to try:
document.getElementById("tryme").innerHTML = "Hello World!";
document.getElementById("tryme").style.fontFamily = "cursive";
document.getElementById("tryme").style.fontSize = "2.0em";
document.getElementById("tryme").innerHTML = 'this is a <a href="">link</a>';
Input a Javascript expression or statement and press enter

In class, you went through this worksheet.html. For more info on style properties that can be set this way, check out the w3c reference on the style object.

Mouse Events

The events that we're most used to in web-browsing are mouse-related — starting, of course, with the click. Any element can be given an onlick attribute whose value is a chunk of Javascript code to be executed whenever the mouse is clicked within that element. Here's a nice example (Note that document.body gives you the DOM body element without the fuss of having to give it an id and go through calling document.getElementById(...)):
Interactive content Code that makes it happen
Clicking anywhere within the bold text causes the background to go red! Refresh the page to return sanity.
Clicking anywhere 
<b onclick='"#ff0000"'>within the bold text</b> 
causes the background to go red!  Refresh the page to return sanity.
There's actually a number of mouse events that are scriptable this way via the following attributes: Exercise: add the word "disclaimer" to the bottom of your webpage (in bold) and make it so that when you click on the word, an alert box pops up saying
The opinions expressed in this webpage are solely those of the author and do not necessarily reflect the opinions of USNA, the Navy, the DoD, the Federal Government, the United Nations or the Galactic Federation.
It should work like this: disclaimer. ← Click on This!

A Mean Trick (You can't always trust the browser)

Check out the following link. Look at what it says, look at the status bar/pop-up. Make sure it's legit and you're getting sent where you think you're getting sent. Only then click.
Check out, the Naval Academy's new home page.
Now this is a truly mean trick. The browser tells you that you're really going to, and yet that's not where we ended up. How did that happen? Here's what the HTML source for that link looked like:
<a id="foo" href="" onclick="document.getElementById('foo').href='';"></a>
See how that worked? Because the onclick script gets run before the browser reads the href attribute to decide where to go, I pulled a switcheroo and had the script change the href address. Mean trick, eh?

Another Mean Trick

Let's try using the other mouse events. Look at the following:
Don't click or anything, just let your mouse pointer pass over the name George. You'll be surprised at what happens.
So we can take any innocuous piece of text in a page and turn it into link that fires whenever the mouse simply passes over it. How did I do that? Here's the source:
Don't click or anything, just let your mouse pointer pass over the name
<span onmouseover='document.location = ""'>George</span>.
You'll be surprised at what happens.
The moral of this story is that we can easily make webpages work in unexpected ways.

Event-driven Javascript for Good, not Evil

Let's look at an example of something nice we might do with event-driven Javascript. Here's a simple word jumble puzzle that lets us show solutions:
The interactive content How it was done
Word Jumble Challenge: WBNOR
show solution
Word Jumble Challenge: WBNOR <span id="sol"></span><br>
<b id="inst" onclick='
if (document.getElementById("inst").innerHTML == "show solution")
  document.getElementById("sol").innerHTML = "&#8594; BROWN";
  document.getElementById("inst").innerHTML = "hide solution";
  document.getElementById("sol").innerHTML = "";
  document.getElementById("inst").innerHTML = "show solution";
'>show solution</b>

It's a bit offputting that the mouse pointer doesn't change when we pass over the show solution or hide solution text to indicate that it's clickable. We can make this happen with HTML quite easily. If you set an element's style attribute to "cursor: pointer;", the mouse icon changes as the mouse passes over the element to a little clicker finger thing.

style="cursor: pointer;"
Exercise: take the word jumble code above and make a web page of it. Then modify it so that the cursor icon changes above the show solution or hide solution text. Check out the many mouse pointer icons you can use in HTML.

Client Side Scripting (forms)

Text Input/Output with Forms

At this point, the only way we've been able to input information to a Javascript program as a user is via the prompt(...) function. This gets a bit cumbersome, especially when there are multiple values to enter. Usually when information is input via a webpage, it's done with HTML forms, which allow us to place multiple text inputs, as well as buttons and sliders and so forth, all in the same page. Here's a nice simple example of form-based I/O. Play with it for a moment:

feet = inches

A nice feature of this converter is that you can enter data in either the feet or inches box, and the program is smart enough to convert in the proper direction to fill the other box. With prompt(...), this would've required two separate inputs, one to specify the number and the other to specify the direction. Here's how this was implemented:
      <form name="convert" onsubmit="return false;">
	<input type="text" 
	       onchange="var f = document.forms.convert.feet.value;
			 document.forms.convert.inches.value = f*12;">
	feet = 
	<input type="text" 
	       onchange="var i = document.forms.convert.inches.value;
			 document.forms.convert.feet.value = i/12;">
Notice that we have a new kind of element: <form>. Form-elements contain user-input elements, like the two input elements in this example. We usually define the name attribute for forms and for the user-input elements they contain, since the DOM allows us to reference input element values by name using the following syntax:
That's why you see document.forms.convert.inches.value, for example. input elements, which are also new, don't have end tags. They do, however, require a type attribute to tell us what kind of input control we're looking for. Setting type="text" gives us a text box. Finally, input elements have an onchange event (in addition to our mouse events from last lesson), that allows us to run a script when the .value of the element changes as a direct result of a user action. input element values are actually attributes, so we can set an initial value as a regular HTML attribute definition. The form attribute onsubmit="return false;" is a bit of a magic incantation. Basically, forms were originally used to send information back to a webserver. We're not trying to do this right now, and setting onsubmit="return false;" is there to stop the browser from actually sending information back. Obviously, there are a number of new features in this one simple example. So, to make sure you follow things, take a look at the units converter in ex3.html. Play with it for a bit, then do a View Source. This is more than a mere units converter, and if you understand the HTML source for it, you should be able to tease a secret message out of the system! There will be code you don't understand on the page, but you should be able to figure out how to get the secret message!

Exercise: Try to modify this units converter to convert between Fahrenheit and Celsius (recall, F = 9/5 C + 32 and C = 5/9(F - 32)). To move one step further, try to add a field for Kelvin to the converter: (K = C + 273.15).

Password Input

Javascript has a special input type for passwords, which works like a text field, except that you only see dots when you type, so someone looking over your shoulder won't see what you've typed. Since all that's different is the type, this doesn't represent much new. Here's an example that doesn't do much, but shows the syntax:

<form onsubmit="return false;"><input type="password"></form>    

Consider the simple example ex4.html. If you know the password, you can reveal a secret message. Can you figure out the message? Give it a try before you move on.

Probably it didn't take too long to get that message. There are some problems here. First of all, figuring out the password was easy, because it was sitting in the HTML source. Second of all, even if we couldn't figure out the password, we could grab uninteresting.js from the website and simply read the message. Normally, authentication, in this case checking a password to make sure the proper person is accessing the data, would be done on a server, not on a client. Giving clients access to the actual password by View Source-ing the page, as we did here is clearly bad news. It's not impossible to embed something like password protection into a client webpage, though. The page ex2.html is an example. This is "crackable", but not obviously so. The message is embedded in the Javascript code, but it is encrypted. You need to know the key to get the message. So even though you see the encrypted message and you see the process by which it is decrypted, you still need the key.


There are many user-input elements available for HTML forms (see w3c's intro), but the last one that we'll look at is the humble button. An input with type="button" is ... a button. The value attribute defines the button's label. A typical thing to do with a button is to set its onclick property to a chunk of Javascript code to do some job. For example, in the following code, clicking on the button squares the value in the field.
Interactive form elementHow it works
<form name="buttonForm" onsubmit="return false;">
	  <input type="text" name="x" value="2">
	  <input type="button" 
		 value="Square It" 
		 onclick="var t = document.forms.buttonForm.x.value; 
                          document.forms.buttonForm.x.value = t*t;">
Exercise: modify the above form by adding a "Squareroot It" button.