Excerpt from: JavaScript for Programmers





5.00/5 (2 votes)
This book is bundled with video training on a two-part DVD, titled JavaScript Fundamentals I and II livelessons (video instruction from technology experts)
|
By Paul J. Deitel and Harvey M. Deitel Published by Prentice Hall ISBN-10: 0-13-700131-2 ISBN-13: 978-0-13-700131-6 |
This sample chapter is an excerpt from the book, JavaScript for Programmers, by Paul Deitel and Harvey Deitel, part of the Deitel Developer Series, copyright 2010 Pearson Education. This book is bundled with video training on a two-part DVD, titled JavaScript Fundamentals I and II livelessons (video instruction from technology experts), including more than 14 hours of expert video instruction by Author Paul Deitel. To see a corresponding sample video clip on “Events”, (Lesson #3, on DVD Part II), please visit the publisher site and click on the “Audio & Video” tab: www.informit.com/title/0137018258 The authors’ site is: http://deitel.com/.
11. JavaScript: Events
The wisest prophets make sure of the event first.
—Horace Walpole
Do you think I can listen all day to such stuff?
—Lewis Carroll
The user should feel in control of the computer; not the other way around. This is achieved in applications that embody three qualities: responsiveness, permissiveness, and consistency.
—Inside Macintosh, Volume 1 Apple Computer, Inc., 1985
We are responsible for actions performed in response to circumstances for which we are not responsible.
—Allan Massie
Objectives
In this chapter you’ll learn:
The concepts of events, event handlers and event bubbling.
To create and register event handlers that respond to mouse and keyboard events.
To use the event
object to get information about an event.
To recognize and respond to common events, including onload
, onmousemove
, onmouseover
, onmouseout
, onfocus
, onblur
, onsubmit
and onreset
.
Outline
11.1 |
Introduction |
11.2 |
Registering Event Handlers |
11.3 |
Event |
11.4 |
Event |
11.5 |
Rollovers with |
11.6 |
Form Processing with |
11.7 |
Form Processing with |
11.8 |
Event Bubbling |
11.9 |
More Events |
11.10 |
Web Resources |
11.1 Introduction
We’ve seen that XHTML pages can be controlled via scripting, and we’ve already used a few events to trigger scripts, such as the onclick
and onsubmit
events. This chapter goes into more detail on JavaScript events, which allow scripts to respond to user interactions and modify the page accordingly. Events allow scripts to respond to a user who is moving the mouse, entering form data or pressing keys. Events and event handling help make web applications more responsive, dynamic and interactive.
In this chapter, we discuss how to set up functions to react when an event fires (occurs). We give examples of event handling for nine common events, including mouse events and form-processing events. A the end of the chapter, we provide a table of the events covered in this chapter and other useful events.
11.2 Registering Event Handlers
Functions that handle events are called event handlers. Assigning an event handler to an event on a DOM node is called registering an event handler. Previously, we have registered event handlers using the inline model, treating events as attributes of XHTML elements (e.g., <p onclick = "myfunction()">
). Another model, known as the traditional model, for registering event handlers is demonstrated alongside the inline model in Fig. 11.1.
Example 11.1. Event registration models.
1 <?xml version = "1.0" encoding = "utf-8"?> 2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 4 5 <!-- Fig. 11.1: registering.html --> 6 <!-- Event registration models. --> 7 <html xmlns = "http://www.w3.org/1999/xhtml"> 8 <head> 9 <title>Event Registration Models</title> 10 <style type = "text/css"> 11 div { padding: 5px; 12 margin: 10px; 13 border: 3px solid #0000BB; 14 width: 12em } 15 </style> 16 <script type = "text/javascript"> 17 <!-- 18 // handle the onclick event regardless of how it was registered 19 function handleEvent() 20 { 21 alert( "The event was successfully handled." ); 22 } // end function handleEvent 23 24 // register the handler using the traditional model 25 function registerHandler() 26 { 27 var traditional = document.getElementById( "traditional" ); 28 traditional.onclick = handleEvent; 29 } // end function registerHandler 30 // --> 31 </script> 32 </head> 33 <body onload = "registerHandler()"> 34 <!-- The event handler is registered inline --> 35 <div id = "inline" onclick = "handleEvent()"> 36 Inline registration model</div> 37 38 <!-- The event handler is registered by function registerHandler --> 39 <div id = "traditional">Traditional registration model</div> 40 </body> 41 </html>
In the earliest event-capable browsers, the inline model was the only way to handle events. Later, Netscape developed the traditional model and Internet Explorer adopted it. Since then, both Netscape and Microsoft have developed separate (incompatible) advanced event models with more functionality than either the inline or the traditional model. Netscape’s advanced model was adapted by the W3C to create a DOM Events Specification. Most browsers support the W3C model, but Internet Explorer 7 does not. This means that to create cross-browser websites, we are mostly limited to the traditional and inline event models. While the advanced models provide more convenience and functionality, most of the features can be implemented with the traditional model.
Line 35 assigns "handleEvent()"
to the onclick
attribute of the div
in lines 35–36. This is the inline model for event registration we’ve seen in previous examples. The div
in line 39 is assigned an event handler using the traditional model. When the body
element (lines 33–40) loads, the registerHandler
function is called.
Function registerHandler
(lines 25–29) uses JavaScript to register the function handleEvent
as the event handler for the onclick
event of the div
with the id "traditional"
. Line 27 gets the div
, and line 28 assigns the function handleEvent
to the div
’s onclick
property.
Notice that in line 28, we do not put handleEvent
in quotes or include parentheses at the end of the function name, as we do in the inline model in line 35. In the inline model, the value of the XHTML attribute is a JavaScript statement to execute when the event occurs. The value of the onclick
property of a DOM node is not an executable statement, but the name of a function to be called when the event occurs. Recall that JavaScript functions can be treated as data (i.e., passed into methods, assigned to variables, etc.).
Common Programming Error 11.1
Putting quotes around the function name when registering it using the inline model would assign a string to the onclick
property of the node—a string cannot be called.
Common Programming Error 11.2
Putting parentheses after the function name when registering it using the inline model would call the function immediately and assign its return value to the onclick
property.
Once the event handler is registered in line 28, the div
in line 39 has the same behavior as the div
in lines 35–36, because handleEvent
(lines 19–22) is set to handle the onclick
event for both div
s. When either div
is clicked, an alert will display "The event was successfully handled."
The traditional model allows us to register event handlers in JavaScript code. This has important implications for what we can do with JavaScript events. For example, traditional event-handler registration allows us to assign event handlers to many elements quickly and easily using repetition statements, instead of adding an inline event handler to each XHTML element. In the remaining examples in this chapter, we use both the inline and traditional registration models depending on which is more convenient.
11.3 Event onload
The onload
event fires whenever an element finishes loading successfully (i.e., all its children are loaded). Frequently, this event is used in the body
element to initiate a script after the page loads in the client’s browser. Figure 11.2 uses the onload
event for this purpose. The script called by the onload
event updates a timer that indicates how many seconds have elapsed since the document was loaded.
Example 11.2. Demonstrating the onload event.
1 <?xml version = "1.0" encoding = "utf-8"?> 2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 4 5 <!-- Fig. 11.2: onload.html --> 6 <!-- Demonstrating the onload event. --> 7 <html xmlns = "http://www.w3.org/1999/xhtml"> 8 <head> 9 <title>onload Event</title> 10 <script type = "text/javascript"> 11 <!-- 12 var seconds = 0; 13 14 // called when the page loads to begin the timer 15 function startTimer() 16 { 17 // 1000 milliseconds = 1 second 18 window.setInterval( "updateTime()", 1000 ); 19 } // end function startTimer 20 21 // called every 1000 ms to update the timer 22 function updateTime() 23 { 24 ++seconds; 25 document.getElementById( "soFar" ).innerHTML = seconds; 26 } // end function updateTime 27 // --> 28 </script> 29 </head> 30 <body onload = "startTimer()"> 31 <p>Seconds you have spent viewing this page so far: 32 <strong id = "soFar">0</strong></p> 33 </body> 34 </html>
Our use of the onload
event occurs in line 30. After the body
section loads, the browser triggers the onload
event. This calls function startTimer
(lines 15–19), which in turn uses method window.setInterval
to specify that function updateTime
(lines 22–26) should be called every 1000
milliseconds. The updateTime
function increments variable seconds
and updates the counter on the page.
Note that we could not have created this program without the onload event, because elements in the XHTML page cannot be accessed until the page has loaded. If a script in the head
attempts to get a DOM node for an XHTML element in the body
, getElementById
returns null
because the body
has not yet loaded. Other uses of the onload
event include opening a pop-up window once a page has loaded and triggering a script when an image or Java applet loads.
Common Programming Error 11.3
Trying to get an element in a page before the page has loaded is a common error. Avoid this by putting your script in a function using the onload
event to call the function.
11.4 Event onmousemove, the event Object and this
This section introduces the onmousemove
event, which fires repeatedly whenever the user moves the mouse over the web page. We also discuss the event
object and the keyword this
, which permit more advanced event-handling capabilities. Figure 11.3 uses onmousemove
and this
to create a simple drawing program that allows the user to draw inside a box in red or blue by holding down the Shift or Ctrl keys.
Example 11.3. Simple drawing program.
1 <?xml version = "1.0" encoding = "utf-8"?> 2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 4 5 <!-- Fig. 11.3: draw.html --> 6 <!-- A simple drawing program. --> 7 <html xmlns = "http://www.w3.org/1999/xhtml"> 8 <head> 9 <title>Simple Drawing Program</title> 10 <style type = "text/css"> 11 #canvas { width: 400px; 12 border: 1px solid #999999; 13 border-collapse: collapse } 14 td { width: 4px; 15 height: 4px } 16 th.key { font-family: arial, helvetica, sans-serif; 17 font-size: 12px; 18 border-bottom: 1px solid #999999 } 19 </style> 20 <script type = "text/javascript"> 21 <!-- 22 //initialization function to insert cells into the table 23 function createCanvas () 24 { 25 var side = 100; 26 var tbody = document.getElementById( "tablebody" ); 27 28 for ( var i = 0; i < side; i++ ) 29 { 30 var row = document.createElement( "tr" ); 31 32 for ( var j = 0; j < side; j++ ) 33 { 34 var cell = document.createElement( "td" ); 35 cell.onmousemove = processMouseMove; 36 row.appendChild( cell ); 37 } // end for 38 39 tbody.appendChild( row ); 40 } // end for 41 } // end function createCanvas 42 43 // processes the onmousemove event 44 function processMouseMove( e ) 45 { 46 // get the event object from IE 47 if ( !e ) 48 var e = window.event; 49 50 // turn the cell blue if the Ctrl key is pressed 51 if ( e.ctrlKey ) 52 this.style.backgroundColor = "blue"; 53 54 // turn the cell red if the Shift key is pressed 55 if ( e.shiftKey ) 56 this.style.backgroundColor = "red"; 57 } // end function processMouseMove 58 // --> 59 </script> 60 </head> 61 <body onload = "createCanvas()"> 62 <table id = "canvas" class = "canvas"><tbody id = "tablebody"> 63 <tr><th class = "key" colspan = "100">Hold <tt>ctrl</tt> 64 to draw blue. Hold <tt>shift</tt> to draw red.</th></tr> 65 </tbody></table> 66 </body> 67 </html>
The XHTML body
has a table
with a tbody
containing one row that gives the user instructions on how to use the program. The body’s onload
attribute (line 61) calls function createCanvas
, which initializes the program by filling in the table.
The createCanvas
function (lines 23–41) fills in the table with a grid of cells. The CSS rule in lines 14–15 sets the width
and height
of every td
element to 4px. Line 11 dictates that the table is 400px
wide. Line 13 uses the border-collapse
CSS property to eliminate space between the table cells.
Line 25 defines variable side
, which determines the number of cells in each row and the number of rows created by the nested for
statements in lines 28–40. We set side
to 100
in order to fill the table with 10,000 4px
cells. Line 26 stores the tbody
element so that we can append rows to it as they are generated.
Common Programming Error 11.4
Although you can omit the tbody
element in an XHTML table, without it you cannot append tr
elements as children of a table
using JavaScript. While Firefox treats appended rows as members of the table body, Internet Explorer will not render any table cells that are dynamically added to a table outside a thead
, tbody
or tfoot
element.
The nested for
statements in lines 28–40 fill the table with a 100 × 100 grid of cells. The outer loop creates each table row, while the inner loop creates each cell. The inner loop uses the createElement
method to create a table cell, assigns function processMouseMove
as the event handler for the cell’s onmousemove
event and appends the cell as a child of the row. The onmousemove
event of an element fires whenever the user moves the mouse over that element.
At this point, the program is initialized and simply calls processMouseMove
whenever the mouse moves over any table cell. The function processMouseMove
(lines 44–57) colors the cell the mouse moves over, depending on the key that is pressed when the event occurs. Lines 44–48 get the event
object, which stores information about the event that called the event-handling function.
Internet Explorer and Firefox do not implement the same event models, so we need to account for some differences in how the event
object can be handled and used. Firefox and other W3C-compliant browsers (e.g., Safari, Opera) pass the event
object as an argument to the event-handling function. Internet Explorer, on the other hand, stores the event object in the event
property of the window
object. To get the event object regardless of the browser, we use a two-step process. Function processMouseMove
takes the parameter e
in line 44 to get the event
object from Firefox. Then, if e
is undefined (i.e., if the client is Internet Explorer), we assign the object in window.event
to e
in line 48.
In addition to providing different ways to access the event
object, Firefox and Internet Explorer also implement different functionality in the event
object itself. However, there are several event
properties that both browsers implement with the same name, and some that both browsers implement with different names. In this book, we use properties that are implemented in both event models, or we write our code to use the correct property depending on the browser—all of our code runs properly in IE7 and Firefox 2 (and higher).
Once e
contains the event
object, we can use it to get information about the event. Lines 51–56 do the actual drawing. The event object’s ctrlKey
property contains a boolean which reflects whether the Ctrl key was pressed during the event. If ctrlKey
is true, line 52 executes, changing the color of a table cell.
To determine which table cell to color, we introduce the this
keyword. The meaning of this
depends on its context. In an event-handling function, this
refers to the DOM object on which the event occurred. Our function uses this
to refer to the table cell over which the mouse moved. The this
keyword allows us to use one event handler to apply a change to one of many DOM elements, depending on which one received the event.
Lines 51–52 change the background color of this
table cell to blue if the Ctrl key is pressed during the event. Similarly, lines 55–56 color the cell red if the Shift key is pressed. To determine this, we use the shiftKey
property of the event
object. This simple function allows the user to draw inside the table on the page in red and blue.
This example demonstrated the ctrlKey
and shiftKey
properties of the event
object. Figure 11.4 lists some important cross-browser properties of the event
object.
Figure 11.4. Some event object properties
Property |
Description |
|
This value is |
|
Set to |
|
The coordinates of the mouse cursor inside the client area (i.e., the active area where the web page is displayed, excluding scrollbars, navigation buttons, etc.). |
|
This value is |
keyCode |
The ASCII code of the key pressed in a keyboard event. |
|
The coordinates of the mouse cursor on the screen coordinate system. |
|
This value is |
|
The name of the event that fired, without the prefix |
This section introduced the event onmousemove
and the keyword this
. We also discussed more advanced event handling using the event
object to get information about the event. The next section continues our introduction of events with the onmouseover
and onmouseout
events.
11.5 Rollovers with onmouseover and onmouseout
Two more events fired by mouse movements are onmouseover
and onmouseout
. When the mouse cursor moves into an element, an onmouseover
event occurs for that element. When the cursor leaves the element, an onmouseout
event occurs. Figure 11.5 uses these events to achieve a rollover effect that updates text when the mouse cursor moves over it. We also introduce a technique for creating rollover images.
Example 11.5. Events onmouseover and onmouseout.
1 <?xml version = "1.0" encoding = "utf-8"?> 2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 4 5 <!-- Fig. 11.5: onmouseoverout.html --> 6 <!-- Events onmouseover and onmouseout. --> 7 <html xmlns = "http://www.w3.org/1999/xhtml"> 8 <head> 9 <title>Events onmouseover and onmouseout</title> 10 <style type = "text/css"> 11 body { background-color: wheat } 12 table { border-style: groove; 13 text-align: center; 14 font-family: monospace; 15 font-weight: bold } 16 td { width: 6em } 17 </style> 18 <script type = "text/javascript"> 19 <!-- 20 image1 = new Image(); 21 image1.src = "heading1.gif"; 22 image2 = new Image(); 23 image2.src = "heading2.gif"; 24 25 function mouseOver( e ) 26 { 27 if ( !e ) 28 var e = window.event; 29 30 var target = getTarget( e ); 31 32 // swap the image when the mouse moves over it 33 if ( target.id == "heading" ) 34 { 35 target.src = image2.src; 36 return; 37 } // end if 38 39 // if an element's id is defined, assign the id to its color 40 // to turn hex code's text the corresponding color 41 if ( target.id ) 42 target.style.color = target.id; 43 } // end function mouseOver 44 45 function mouseOut( e ) 46 { 47 if ( !e ) 48 var e = window.event; 49 50 var target = getTarget( e ); 51 52 // put the original image back when the mouse moves away 53 if ( target.id == "heading" ) 54 { 55 target.src = image1.src; 56 return; 57 } // end if 58 59 // if an element's id is defined, assign id to innerHTML 60 // to display the color name 61 if ( target.id ) 62 target.innerHTML = target.id; 63 } // end function mouseOut 64 65 // return either e.srcElement or e.target, whichever exists 66 function getTarget( e ) 67 { 68 if ( e.srcElement ) 69 return e.srcElement; 70 else 71 return e.target; 72 } // end function getTarget 73 74 document.onmouseover = mouseOver; 75 document.onmouseout = mouseOut; 76 // --> 77 </script> 78 </head> 79 <body> 80 <img src = "heading1.gif" id = "heading" alt = "Heading Image" /> 81 <p>Can you tell a color from its hexadecimal RGB code 82 value? Look at the hex code, guess its color. To see 83 what color it corresponds to, move the mouse over the 84 hex code. Moving the mouse out of the hex code's table 85 cell will display the color name.</p> 86 <table> 87 <tr> 88 <td id = "Black">#000000</td> 89 <td id = "Blue">#0000FF</td> 90 <td id = "Magenta">#FF00FF</td> 91 <td id = "Gray">#808080</td> 92 </tr> 93 <tr> 94 <td id = "Green">#008000</td> 95 <td id = "Lime">#00FF00</td> 96 <td id = "Maroon">#800000</td> 97 <td id = "Navy">#000080</td> 98 </tr> 99 <tr> 100 <td id = "Olive">#808000</td> 101 <td id = "Purple">#800080</td> 102 <td id = "Red">#FF0000</td> 103 <td id = "Silver">#C0C0C0</td> 104 </tr> 105 <tr> 106 <td id = "Cyan">#00FFFF</td> 107 <td id = "Teal">#008080</td> 108 <td id = "Yellow">#FFFF00</td> 109 <td id = "White">#FFFFFF</td> 110 </tr> 111 </table> 112 </body> 113 </html>
To create a rollover effect for the image in the heading, lines 20–23 create two new JavaScript Image
objects—image1
and image2
. Image image2
displays when the mouse hovers over the image. Image image1
displays when the mouse is outside the image. The script sets the src
properties of each Image
in lines 21 and 23, respectively. Creating Image
objects preloads the images (i.e., loads the images in advance), so the browser does not need to download the rollover image the first time the script displays the image. If the image is large or the connection is slow, downloading would cause a noticeable delay in the image update.
Performance Tip 11.1
Preloading images used in rollover effects prevents a delay the first time an image is displayed.
Functions mouseOver
and mouseOut
are set to process the onmouseover
and onmouseout
events, respectively, in lines 74–75. Both functions begin (lines 25–28 and 45–48) by getting the event
object and using function getTarget
to find the element that received the action. Because of browser event model differences, we need getTarget
(defined in lines 66–72) to return the DOM node targeted by the action. In Internet Explorer, this node is stored in the event
object’s srcElement
property. In Firefox, it is stored in the event
object’s target
property. Lines 68–71 return the node using the correct property to hide the browser differences from the rest of our program. We must use function getTarget
instead of this
because we do not define an event handler for each specific element in the document
. In this case, using this
would return the entire document. In both mouseOver
and mouseOut
, we assign the return value of getTarget
to variable target
(lines 30 and 50).
Lines 33–37 in the mouseOver
function handle the onmouseover
event for the heading image by setting its src
attribute (target.src
) to the src
property of the appropriate Image
object (image2.src
). The same task occurs with image1
in the mouseOut
function (lines 53–57).
The script handles the onmouseover
event for the table cells in lines 41–42. This code tests whether an id
is specified, which is true only for our hex code table cells and the heading image in this example. If the element receiving the action has an id
, the code changes the color of the element to match the color name stored in the id
. As you can see in the code for the table
(lines 86–111), each td
element containing a color code has an id
attribute set to one of the 16 basic XHTML colors. Lines 61–62 handle the onmouseout
event by changing the text in the table cell the mouse cursor just left to match the color that it represents.
11.6 Form Processing with onfocus and onblur
The onfocus
and onblur
events are particularly useful when dealing with form elements that allow user input (Fig. 11.6). The onfocus
event fires when an element gains focus (i.e., when the user clicks a form field or uses the Tab key to move between form elements), and onblur
fires when an element loses focus, which occurs when another control gains the focus. In lines 31–32, the script changes the text inside the div
below the form (line 58) based on the messageNum
passed to function helpText
(lines 29–33). Each of the elements of the form, such as the name
input in lines 40–41, passes a different value to the helpText
function when it gains focus (and its onfocus
event fires). These values are used as indices for helpArray
, which is declared and initialized in lines 17–27 and stores help messages. When elements lose focus, they all pass the value 6
to helpText
to clear the tip div
(note that the empty string ""
is stored in the last element of the array).
Example 11.6. Demonstrating the onfocus and onblur events.
1 <?xml version = "1.0" encoding = "utf-8"?> 2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 4 5 <!-- Fig. 11.6: onfocusblur.html --> 6 <!-- Demonstrating the onfocus and onblur events. --> 7 <html xmlns = "http://www.w3.org/1999/xhtml"> 8 <head> 9 <title>A Form Using onfocus and onblur</title> 10 <style type = "text/css"> 11 .tip { font-family: sans-serif; 12 color: blue; 13 font-size: 12px } 14 </style> 15 <script type = "text/javascript"> 16 <!-- 17 var helpArray = 18 [ "Enter your name in this input box.", // element 0 19 "Enter your e-mail address in this input box, " + 20 "in the format user@domain.", // element 1 21 "Check this box if you liked our site.", // element 2 22 "In this box, enter any comments you would " + 23 "like us to read.", // element 3 24 "This button submits the form to the " + 25 "server-side script.", // element 4 26 "This button clears the form.", // element 5 27 "" ]; // element 6 28 29 function helpText( messageNum ) 30 { 31 document.getElementById( "tip" ).innerHTML = 32 helpArray[ messageNum ]; 33 } // end function helpText 34 // --> 35 </script> 36 </head> 37 <body> 38 <form id = "myForm" action = ""> 39 <div> 40 Name: <input type = "text" name = "name" 41 onfocus = "helpText(0)" onblur = "helpText(6)" /><br /> 42 E-mail: <input type = "text" name = "e-mail" 43 onfocus = "helpText(1)" onblur = "helpText(6)" /><br /> 44 Click here if you like this site 45 <input type = "checkbox" name = "like" onfocus = 46 "helpText(2)" onblur = "helpText(6)" /><br /><hr /> 47 48 Any comments?<br /> 49 <textarea name = "comments" rows = "5" cols = "45" 50 onfocus = "helpText(3)" onblur = "helpText(6)"></textarea> 51 <br /> 52 <input type = "submit" value = "Submit" onfocus = 53 "helpText(4)" onblur = "helpText(6)" /> 54 <input type = "reset" value = "Reset" onfocus = 55 "helpText(5)" onblur = "helpText(6)" /> 56 </div> 57 </form> 58 <div id = "tip" class = "tip"></div> 59 </body> 60 </html>
11.7 Form Processing with onsubmit and onreset
Two more useful events for processing forms are onsubmit
and onreset
. These events fire when a form is submitted or reset, respectively (Fig. 11.7). Function registerEvents
(lines 35–46) registers the event handlers for the form after the body has loaded.
Example 11.7. Demonstrating the onsubmit
and onreset
events.
1 <?xml version = "1.0" encoding = "utf-8"?> 2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 4 5 <!-- Fig. 11.7: onsubmitreset.html --> 6 <!-- Demonstrating the onsubmit and onreset events. --> 7 <html xmlns = "http://www.w3.org/1999/xhtml"> 8 <head> 9 <title>A Form Using onsubmit and onreset</title> 10 <style type = "text/css"> 11 .tip { font-family: sans-serif; 12 color: blue; 13 font-size: 12px } 14 </style> 15 <script type = "text/javascript"> 16 <!-- 17 var helpArray = 18 [ "Enter your name in this input box.", 19 "Enter your e-mail address in this input box, " + 20 "in the format user@domain.", 21 "Check this box if you liked our site.", 22 "In this box, enter any comments you would " + 23 "like us to read.", 24 "This button submits the form to the " + 25 "server-side script.", 26 "This button clears the form.", 27 "" ]; 28 29 function helpText( messageNum ) 30 { 31 document.getElementById( "tip" ).innerHTML = 32 helpArray[ messageNum ]; 33 } // end function helpText 34 35 function registerEvents() 36 { 37 document.getElementById( "myForm" ).onsubmit = function() 38 { 39 return confirm( "Are you sure you want to submit?" ); 40 } // end anonymous function 41 42 document.getElementById( "myForm" ).onreset = function() 43 { 44 return confirm( "Are you sure you want to reset?" ); 45 } // end anonymous function 46 } // end function registerEvents 47 // --> 48 </script> 49 </head> 50 <body onload = "registerEvents()"> 51 <form id = "myForm" action = ""> 52 <div> 53 Name: <input type = "text" name = "name" 54 onfocus = "helpText(0)" onblur = "helpText(6)" /><br /> 55 E-mail: <input type = "text" name = "e-mail" 56 onfocus = "helpText(1)" onblur = "helpText(6)" /><br /> 57 Click here if you like this site 58 <input type = "checkbox" name = "like" onfocus = 59 "helpText(2)" onblur = "helpText(6)" /><br /><hr /> 60 61 Any comments?<br /> 62 <textarea name = "comments" rows = "5" cols = "45" 63 onfocus = "helpText(3)" onblur = "helpText(6)"></textarea> 64 <br /> 65 <input type = "submit" value = "Submit" onfocus = 66 "helpText(4)" onblur = "helpText(6)" /> 67 <input type = "reset" value = "Reset" onfocus = 68 "helpText(5)" onblur = "helpText(6)" /> 69 </div> 70 </form> 71 <div id = "tip" class = "tip"></div> 72 </body> 73 </html>
Lines 37–40 and 42–45 introduce several new concepts. Line 37 gets the form
element ("myForm"
, lines 51–70), then lines 37–40 assign an anonymous function to its onsubmit
property. An anonymous function is defined with no name—it is created in nearly the same way as any other function, but with no identifier after the keyword function
. This notation is useful when creating a function for the sole purpose of assigning it to an event handler. We never call the function ourselves, so we don’t need to give it a name, and it’s more concise to create the function and register it as an event handler at the same time.
The anonymous function (lines 37–40) assigned to the onsubmit
property of myForm
executes in response to the user submitting the form (i.e., clicking the Submit button or pressing the Enter key). Line 39 introduces the confirm
method of the window object. As with alert
, we do not need to prefix the call with the object name window
and the dot (.
) operator. The confirm dialog asks the users a question, presenting them with an OK button and a Cancel button. If the user clicks OK, confirm
returns true
; otherwise, confirm
returns false
.
Our event handlers for the form’s onsubmit
and onreset
events simply return the value of the confirm
dialog, which asks the users if they are sure they want to submit or reset (lines 39 and 44, respectively). By returning either true
or false
, the event handlers dictate whether the default action for the event—in this case submitting or resetting the form—is taken. (Recall that we also returned false
from some event-handling functions to prevent forms from submitting in Chapter 10.) Other default actions, such as following a hyperlink, can be prevented by returning false
from an onclick
event handler on the link. If an event handler returns true
or does not return a value, the default action is taken once the event handler finishes executing.
11.8 Event Bubbling
Event bubbling is the process by which events fired in child elements “bubble” up to their parent elements. When an event is fired on an element, it is first delivered to the element’s event handler (if any), then to the parent element’s event handler (if any). This might result in event handling that was not intended. If you intend to handle an event in a child element alone, you should cancel the bubbling of the event in the child element’s event-handling code by using the cancelBubble
property of the event
object, as shown in Fig. 11.8.
Example 11.8. Canceling event bubbling.
1 <?xml version = "1.0" encoding = "utf-8"?> 2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 3 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 4 5 <!-- Fig. 11.8: bubbling.html --> 6 <!-- Canceling event bubbling. --> 7 <html xmlns = "http://www.w3.org/1999/xhtml"> 8 <head> 9 <title>Event Bubbling</title> 10 <script type = "text/javascript"> 11 <!-- 12 function documentClick() 13 { 14 alert( "You clicked in the document." ); 15 } // end function documentClick 16 17 function bubble( e ) 18 { 19 if ( !e ) 20 var e = window.event; 21 22 alert( "This will bubble." ); 23 e.cancelBubble = false; 24 } // end function bubble 25 26 function noBubble( e ) 27 { 28 if ( !e ) 29 var e = window.event; 30 31 alert( "This will not bubble." ); 32 e.cancelBubble = true; 33 } // end function noBubble 34 35 function registerEvents() 36 { 37 document.onclick = documentClick; 38 document.getElementById( "bubble" ).onclick = bubble; 39 document.getElementById( "noBubble" ).onclick = noBubble; 40 } // end function registerEvents 41 // --> 42 </script> 43 </head> 44 <body onload = "registerEvents()"> 45 <p id = "bubble">Bubbling enabled.</p> 46 <p id = "noBubble">Bubbling disabled.</p> 47 </body> 48 </html>
Clicking the first p
element (line 45) triggers a call to bubble
. Then, because line 37 registers the document
’s onclick
event, documentClick
is also called. This occurs because the onclick
event bubbles up to the document
. This is probably not the desired result. Clicking the second p
element (line 46) calls noBubble
, which disables the event bubbling for this event by setting the cancelBubble
property of the event
object to true
. [Note: The default value of cancelBubble
is false
, so the statement in line 23 is unnecessary.]
Common Programming Error 11.5
Forgetting to cancel event bubbling when necessary may cause unexpected results in your scripts.
11.9 More Events
The events we covered in this chapter are among the most commonly used. A list of some events supported by both Firefox and Internet Explorer is given with descriptions in Fig. 11.9.
Figure 11.9: Cross-browser events.
Event |
Fires when |
|
Image transfer has been interrupted by user. |
|
A new choice is made in a |
|
The user clicks using the mouse. |
|
The mouse is double clicked. |
onfocus |
A form element gains focus. |
|
The user pushes down a key. |
|
The user presses then releases a key. |
|
The user releases a key. |
|
An element and all its children have loaded. |
|
A mouse button is pressed down. |
|
The mouse moves. |
|
The mouse leaves an element. |
|
The mouse enters an element. |
|
A mouse button is released. |
|
A form resets (i.e., the user clicks a reset button). |
|
The size of an object changes (i.e., the user resizes a window or frame). |
|
A text selection begins (applies to |
onsubmit |
A form is submitted. |
|
A page is about to unload. |
11.10 Web Resources
http://www.quirksmode.org/js/introevents.html
An introduction and reference site for JavaScript events. Includes comprehensive information on history of events, the different event models, and making events work across multiple browsers.
wsabstract.com/dhtmltutors/domevent1.shtml
This JavaScript Kit tutorial introduces event handling and discusses the W3C DOM advanced event model.
http://www.w3schools.com/jsref/jsref_events.asp
The W3 School’s JavaScript Event Reference site has a comprehensive list of JavaScript events, a description of their usage and their browser compatibilities.
http://www.brainjar.com/dhtml/events/
BrainJar.com’s DOM Event Model site provdes a comprehensive introduction to the DOM event model, and has example code to demonstrate several different ways of assigning and using events.