While the purpose of the event handler is to respond to a user or system action, most of your event-related scripts concern themselves with processing the event. The next section details how you instruct an element to hand off event processing to a script function. Before getting into that, however, it's helpful to understand that the function can read detailed information about the event through an event object.
Each event that occurs causes the browser to create an event object. Only one such "live" object exists at any instant, even if events fire in quick succession. For example, if you press and release a keyboard key, three events fire in a set sequence (onkeydown, onkeypress, and onkeyup in that order). But if you have a script function that takes a few seconds to process the onkeydown event, the browser holds the other events in an event queue (unreachable through JavaScript) until all script execution triggered by the onkeydown event finishes. Then the event object assumes the identity of the onkeypress event. Users don't realize how many (and how quickly) event objects come and go inside the browser while they type on the keyboard and roll the mouse around the table.
Despite all the work that has gone into the W3C DOM's event model (implemented in Netscape 6 and later), Microsoft continues to deploy its own event model as of IE 6 for Windows. In truth, the two event models share many features, but the syntax is not identical, especially the property names of the event objects that scripts must read to learn details about an event. Let's start, however, with where an event object "lives."
Note that although certain aspects of the comparatively early Navigator 4 event model found their way into the W3C event model, a lot of what you may have learned for that browser is no longer implemented in succeeding Netscape versions. The first edition of this book described the Navigator 4 model in depth. This edition focuses on implementation issues concerning event models and objects for browsers in current release. You can still find Navigator 4 event object reference details in Chapter 9 of this edition.
In IE 4 and later, the event object is a property of the window object. Because the window object is always assumed in client-side scripting, you can reference an IE event object according to the following format:
event.propertyName
Of course, the primary event handler function can access the event object through the event.propertyName syntax. But the browser is also smart enough to know that if the primary function invokes another function, the current event is still being processed, so the event object holds onto its original properties. Only when the last statement of the processing chain completes does the event object stand ready to take on the next event's properties.
The W3C event object requires slightly different handling to make sure that functions can access event properties. Under the W3C DOM, the event object gets passed to an event handler function, and the function must explicitly define a function parameter to receive that object reference. For most event binding approaches (described later in this chapter), the browser automatically takes care of conveying the object reference as an argument to the primary event handler function. Scripters experienced with the Navigator 4 event model will see the similarity in this mechanism. If you are designing in a strictly W3C DOM platform, you can use syntax such as the following to provide your functions with a reference to the incoming object reference:
function myFunction(event) { // local var 'event' refers to current event ... }
Inside such a function, the expression format event.propertyName looks just like the IE format.
The easily conquered challenge is how to allow both event objects and event models to coexist in one page. A tiny bit of object detection allows you to equalize references to the event object for both models, as shown here:
function myFunction(evt) { evt = (evt) ? evt : ((event) ? event : null); // local var 'evt' refers to current event ... }
Inside the function, it's safer to use a local variable whose name does not risk conflicting with the global IE event object's name. Examples in this book use the evt local variable to contain event object references. More commonly, an event handler function wants to reference the element object whose event handler invokes the event. To see how to do that, we'll compare the property sets of the IE and W3C event objects.
Except for a handful of frequently-used and important properties, the IE and W3C event objects share a number of property names. Table 6-3 lists the most common DHTML-related event object properties in both event models, plus several position-related properties from Netscape 6 and later that are not part of the W3C event model.
IE property |
Description |
W3C property or method |
---|---|---|
altKey |
The Alt key was pressed during the event (Boolean) |
altKey |
button |
The mouse button pressed in the mouse event (Integer, but different numbering systems per model) |
button |
cancelBubble |
Whether the event should bubble further |
stopPropagation( ) |
clientX, clientY |
The horizontal and vertical coordinates of the event in the content region of browser window |
clientX, clientY |
ctrlKey |
The Ctrl key was pressed during the event (Boolean) |
ctrlKey |
fromElement |
The object or element from which the pointer moved for a mouseover or mouseout event |
relatedTarget |
keyCode |
The keyboard character code of a keyboard event (Integer) |
keyCode |
offsetX, offsetY |
The horizontal and vertical coordinates of the event within the element space |
Calculated from other properties |
Calculated from other properties |
The horizontal and vertical coordinates of the event within the document space (Netscape only) |
pageX, pageY |
returnValue |
The value returned to the system by the event (used to prevent default action in IE) |
preventDefault( ) |
screenX, screenY |
The horizontal and vertical coordinates of the event relative to the screen |
screenX, screenY |
shiftKey |
The Shift key was pressed during event (Boolean) |
shiftKey |
srcElement |
The object or element intended to receive the event |
target |
toElement |
The object or element to which the pointer moved for a mouseover or mouseout event |
relatedTarget |
type |
The name of the event (without "on" prefix) |
type |
x, y |
The horizontal and vertical coordinates of the event within body element (for unpositioned target) or relative-positioned element |
layerX, layerY |
Of all the properties listed in Table 6-3, the pair that you will most likely call upon are the ones that refer to the element from which the event object was created. Microsoft calls the element the srcElement, while the W3C calls it the target. For a given event handler executing in either browser, the respective properties return a valid reference to the same element. Using object detection techniques, a typical skeleton structure for an event handler function is as follows:
function myFunction(evt) { evt = (evt) ? evt : ((event) ? event : null); if (evt) { var elem = (evt.target) ? evt.target : ((evt.srcElement) ? evt.srcElement : null); if (elem) { // act on element receiving event ... } } }
Once your script has a reference to the element receiving the event, it's easy to use identical, cross-DOM syntax for many DHTML operations, such as modifying style property values. Obviously, this kind of branching is needed only when you must refer to incompatible property names. For event data on mouse button or keyboard actions, you can work directly from the equalized reference to the event object.
Copyright © 2003 O'Reilly & Associates. All rights reserved.