The First Event: load
Typically, the first thing you want JavaScript to do is set up the initial state of the page so it’s ready for use. A very common part of this initialization process is to attach event listeners to the elements in the DOM that will respond to user actions, and you can’t do that until the DOM has loaded into the browser.
For example, you might want to attach blur events to the text fields of a form so you can detect when the user clicks or tabs away from them. You can then immediately validate the text the user entered.
To help you ensure that you are working with a DOM that actually exists, a load event is issued when the page is entirely loaded into the browser window. You can use the onload handler to detect this event and trigger the JavaScript functions that will set up the initial page state for the user. Then you know that the DOM is ready.
Here’s a simple example of how to do this:
In the highlighted line that calls the init function, you can see that there are no parentheses after the init function name. You would normally add parentheses after a function name because you would want the function to run immediately at that point in the code. However, because you are setting up an event that will call the function at a later time, you don’t do that here. If you wrote
window.onload=init();
the function would run immediately (setting the onload property to the result of the function!) and not wait for a page load event to be sent.
Also note that you write window.onload=init because onload is a method of the window object, so you must always precede it with window. for it to work.
By omitting the parentheses when you assign the init function to the onLoad property, the function does not run immediately; instead, it runs when the load event occurs after the page is fully loaded.
The onload handler is very important in every JavaScript application because it is used to initialize the page state; that is, to set up all the event responses that the interface will provide to the user. If you are looking at an existing piece of JavaScript and trying to determine what it does, the best place to start is with the function that is called by the load event—everything flows out from there.
Also note that any JavaScript statement not enclosed in a function and just “loose” on the page runs as soon as it loads. For this reason, it’s very unusual to place any JavaScript except the onload event assignment outside of a function.
Adding Event Listeners on Page Load
After all this discussion, I’ll now show you a simple example of event listeners that are added to an element when the page loads. In this case, when the onload event handler calls the init function, it will add event listeners to a text field.
As a result of the functions called by these event listeners, the text field will highlight (its background property will be set to green) when the field receives focus; it will unhighlight (the default white background will be restored) when the focus is removed. I’ll do this using the addEvent helper function I showed earlier, so that it works on both W3C and Microsoft browsers.
Here’s the form field input.
<input id="email" name="email" type="text" size="24" />
It’s the only HTML element that is relevant to this demo, so I’ll leave the rest of the markup to your imagination—you can see it in the download file.
Step one is to ensure the load event is triggering the function that will set up the event listeners.
Code 4.1. hilite_field_basic1.html
window.onload=setUpFieldEvents; function setUpFieldEvents() { alert ("called"); }
Figure 4.1 shows that when the page loads, the function is called.
Figure 4.1 The function is successfully called from the onload event handler.
Next, I’ll add the code that actually adds the event listeners to the field. To do this, I’ll use the addEvent helper function.
Code 4.2. hilite_field_basic2.html
Because it’s not contained in a function, the highlighted onload event is set up when that line of code loads in the browser, and then the setUpFieldEvents function is called when the page has completely loaded. This causes the two event listeners to be added to the field via the addEvent helper function. Now, when the field gets focus, the addHighlight function will be called; when the field loses focus (blurs), the removeHighlight function will be called.
To ensure this step is working, you can simply add the functions, with temporary alerts, for the two events.
Code 4.3. hilite_field_basic2.html
function addHighlight() { alert("addHighlight called"); } function removeHighlight() { alert("removeHighlight called"); }
Then click in the field, and you will see the alert dialog shown in Figure 4.2.
Figure 4.2 When the field receives focus, the addHighlight function is called.
OK the alert and then click away from the field. You will see the alert dialog shown in Figure 4.3.
Figure 4.3 When the field loses focus, the removeHighlight function is called.
Once the functions are successfully triggered by the events, all you need to do is replace the alerts with the code to highlight and unhighlight the field.
Code 4.4. hilite_field_basic3.html
Now the field’s background becomes green when it receives focus as shown in Figure 4.4. The normal white background color is restored when the field loses focus as shown in Figure 4.5.
Figure 4.4 The background of the field now changes color when it receives focus.
Figure 4.5 The background of the field is restored to its default color when it loses focus.
While this example serves to show a simple implementation of event listeners, it does not take full advantage of the power that event listeners offer. In the preceding example, the functions that were called by the event listeners then use getElementById to get the field before changing its background style. Hard coding the event’s element into the function in this way limits its flexibility: This function can only provide a response to events on this one field.
It is, in fact, unnecessary to get the element at this point because, as mentioned in the introduction of the chapter, event handlers provide the functions they call with access to the name of the object to which they are attached and their triggering event. Once you understand how to take advantage of this feature, you will be able to write event handling code that is both versatile and compact.