Modern Web sites are highly interactive: Dynamic navigation menus, image rollovers, forms, and even drag and drop are available. A common factor among all such sites is some kind of technique for associating a behavior with a specific part of the document. Unfortunately, current practice is something of a jumble of script-heavy approaches, especially in cases where code needs to work on multiple browsers.
Listing 1 shows some of the variation that's possible. It defines two
event handlers, one for the
and one for the
event. One is written in VBScript, and attached through a less-common
technique involving extra attributes on the
script element. The other is written in ECMAscript
Listing 1. Two kinds of events
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <title>Intrinsic Events</title> <script event="onload" for="window" language="vbscript"> <!-- alert "hello" --> </script> </head> <body onunload="alert('goodbye')"> </body> </html>
When viewed in Microsoft Internet Explorer or another browser that supports VBScript, an alert box displaying "hello" appears upon loading the document. In nearly all browsers, "goodbye" appears upon closing the window or navigating to another page. To fully describe what's going on here, you need to understand DOM Events, currently specified by a W3C document entitled Document Object Model (DOM) Level 2 Events Specification (see Resources).
What exactly is an event? For purposes of this discussion, it's best
not to think about it in the traditional sense of the word "event", but
rather as a simple data structure that contains details about something
that's changing. For example, on a
event, the interesting information in the event object is the mouse
pointer coordinates, which mouse buttons are depressed, whether modifier
keys like "shift" are currently depressed, and so on. An individual
event object is short-lived, and exists only long enough for immediate
processing before it ceases to be.
Every event has a target, the XML or HTML
element most closely associated with the event. An event handler is a piece of executable code or markup
that responds to a particular event. Distinct from any handler, some
events, such as clicking on a hyperlink, can cause activity called a
default action. In Listing 1, the target of the
unload event is the
body element, and the event handler is the bit of
script inside the
The easiest and most common technique is to attach event handlers right at the target, and once upon a time this technique was all that browsers supported. However, this often isn't practical. Listing 2 offers one example:
Listing 2. Demonstrating the need for event observers
<p>You want to capture all clicks on this paragraph, even if the text has <em>special markup</em>.</p>
In Listing 2, suppose you have an event handler in place to handle
click events targeted at the
p element. If the user happens to click on the
words "special markup", this will create an event targeted at the
em element. Because the paragraph isn't the target,
its click handler will not fire. Getting this to work involves placing
an event observer on the
p element that can respond to events targeted at
itself or any of its children.
DOM Level 2 Events describes how an event handler can be connected in a way that solves the problem shown in Listing 2 -- though it may be more complex than necessary due to ancient browser history (earlier versions of Internet Explorer and Netscape had their own idiosyncrasies, and some of them were grandfathered in to the official DOM spec). An event takes an imaginary journey, known as propagation, through the tree structure of the document. Actually, it takes two journeys: The first, called capture, begins at the document root and proceeds to the target element. After a chance for ordinary target processing, a second journey, called bubbling, starts at the target element and ends up back at the document root. During each phase, any element along the path can be registered as an observer of the event, and can thus trigger an event handler. Events can even be stopped from further propagation, which prevents later observers from detecting that the event happened. Figure 1 illustrates propagation, in a tree structure with a root, <html>, <body>, <p>, and <em>. Arrows labeled 'capture' lead from the root to <em>, which is labeled 'target'. Arrows from the target back to the root are labeled 'bubble'. The <p> element is also labeled 'observer'.
Figure 1. Event propagation
If you need to set up an event observer, should you use the capture or bubbling phase? Here are a few guidelines:
- If you're dealing with only a single observation point, which is usually the case, you can use either the capture or bubbling phase -- there's no real difference. The distinction only matters if a single event will be observed from multiple places in the document tree.
- Some events like
focusdo not participate in the bubbling phase, and thus can only be observed during the capture phase or directly at the target.
- When multiple observers are present, use the bubbling phase if you
want closer observers to fire first. For example, suppose that in Figure 1
there were observers on both
p. With capture, the observer on
bodywould fire first, followed by the one on
p. With bubbling, the observer on
pwould fire first, followed by the one on
- Keep in mind that the HTML 4.0-style attribute syntax, used for
onunloadin Listing 1, registers observers for the bubbling phase.
- Whether the bubbling or capture phase is used, the default action always happens after all event propagation is finished. Stopping the event propagation doesn't by itself prevent the default action. A separate API feature allows the default action to be cancelled, regardless of whatever else happens during propagation.
The DOM Events specification defines a way to attach event observers from script, as shown here in Listing 3.
Listing 3. Attaching event observers
var el = document.getElementById('observer_element_id'); el.addEventListener("mouseover", highlight_func, true); el.addEventListener("mouseout", normal_func, true);
In the call to
addEventListener, the first
parameter is the event name, the second parameter is a function
reference that will get executed, and the third parameter is either
true (indicating the capture phase) or
false (for bubbling). The DOM Events specification
defines a number of core events, as well as an API method to stop the
propagation of an event, and cancel the default action associated with
It's worth noting that there are significant differences in
various browser implementations of these APIs. In particular, Internet Explorer up to
version 6 doesn't support
but instead uses a similar function named
Up to this point, everything about events has been tied to procedural script. The XML Events specification builds upon the foundation of DOM Level 2 Events, adding a declarative way to hook up event observers. The W3C XForms specification (see Resources) is one of the first to define a library of XML Events-compatible elements that can accomplish common tasks declaratively. Listing 4 shows an example of this in XForms. (For the complete namespace declarations in use here, see the full example in Listing 5.)
Listing 4. Declarative event handlers
<xf:trigger> <xf:label>Reset the form</xf:label> <xf:reset ev:event="DOMActivate" model="mymodel" /> </xf:trigger>
XML Events is defined as a number of attributes. In Listing 4, the
ev:event attribute specifies the specific
event being listened for; the handler is the
xf:reset element, and the observer defaults to
the parent element,
that no script is needed in this listing.
The XML Events specification consists mainly of the definitions of
attributes that can be placed on existing elements, along with a
listener element that can also host the attributes.
Each attribute maps to a feature of DOM Level 2 events. Table 1 lists
all the XML Events attributes.
Table 1. XML Events attributes
|As shown in Listing 4, this required attribute names the event that triggers the listener.|
|This attribute points to the unique ID of an element that is the observer.|
|This attribute points to the URI of an element, possibly in a different document, that performs some action or processing.|
|This attribute causes the listener to respond only to events directed at the specific target, and you should only use it in special situations.|
|This attribute allows a document-unique identifier to be given to the |
Listing 4 shows a convenient way to use XML Events with the minimum
possible number of attributes: XML Events attributes are attached
directly to the handler element. Whenever the
ev:handler attribute is omitted, the element
bearing the XML Events attributes is considered the handler. The
observer is either specified through the
ev:observer attribute, or the parent element. In
Listing 4, the observer is
Another kind of defaulting allows the XML Events attributes to be
attached to the observer element when the
ev:observer attribute is absent but the
ev:handler attribute is present.
Listing 5 recreates the behavior in Listing 1, showing both defaulting techniques and using both script and a declarative action.
Listing 5. Two ways to use XML Events
script element here is a handler,
attached to an observer on
body element). The
xf:message element by itself doesn't do anything,
but the observer element (
body again) points
back to it, registering the event handler.
Script is clearly useful for many things. Even so, it still can be difficult to accomplish certain tasks through scripting. XML Events offers a uniform syntax for declaratively attaching scripts to documents, and even makes it possible to define behaviors that work without a dependency on a script interpreter. XML Events is now used by an increasing number of markup technologies, including XForms, XHTML, SVG, and others. In a future article, I will go into more detail on how to use and implement XML Events.
- Read the ECMAScript standard, which officially defines the widely-implemented scripting language
- Gain a deeper insight into event flow -- consult The DOM Level 2 Events Specification, a W3C Recommendation.
- Next, have a look at the well-written XML
Events specification, also a W3C Recommendation.
- Get a slightly different angle on understanding XML Events. Read Steven Pemberton's
Events for HTML Authors" on the W3C site.
- Consult the Working Draft of
Accessibility Guidelines 2.0 and the documents linked to it, for
advice on deciding which events you need to work with, and a
host of other accessibility issues.
- To see a real-world example of declarative actions based on XML Events, examine the XForms Actions
chapter of the W3C XForms specification. While you're at it, take a look at Micah Dubinko's recent developerWorks article "Inside the XForms Validator" (September 2004).
- Read the full text of Micah Dubinko's O'Reilly book XForms Essentials
online, including a chapter on events. You can also order the book
developerWorks Developer Bookstore.
- Want a more complete understanding of how all the major XML standards interrelate?
Check out Uche Ogbuji's excellent four-part survey of XML standards here on developerWorks:
- Part 1 -- The core standards (January 2004)
- Part 2 -- XML processing standards (February 2004)
- Part 3 -- The most important vocabularies (February 2004)
- Part 4 -- Detailed cross-reference of the most important XML standards (March 2004)
- Find more XML resources on the developerWorks XML zone.
- Learn how you can become an IBM Certified Developer in XML and related technologies.
Micah Dubinko is a consultant and founder of Brain Attic, L.L.C., a software vendor and consultancy specializing in defeating information overload. He wrote XForms Essentials for O'Reilly Media and served on the Working Group that developed XForms 1.0. He lives and works in Phoenix, AZ. You can contact him at email@example.com.