Nancy Winnick Cluts
Developer Technology Engineer
Microsoft Corporation
March 9, 1998
Contents
Introduction
DHTML Events
Bubble, Bubble, Toil and Trouble
Cancelling the Default Action
Summary
Those of you who are Microsoft® Windows®, OS/2, or UNIX programmers already understand the concept of event handling. Within Windows, it is common practice for a programmer to trap events and call a function in response. For example, when you click a button in a dialog box, the code that is written to handle the dialog box includes code that is called when a button is pressed. The button press is the event and the function that is subsequently called is the action. Events are not new to Internet Explorer 4.0; you were able to trap events on a small subset of HTML elements in Internet Explorer 3. x as well as Navigator. With Internet Explorer 4.0 and Dynamic HTML (DHTML), all elements are the source of events and properties. Before we go on, let's define some terms:
Term | Definition |
Event | A notification that occurs in response to an action. |
Event handler | A function or routine written in a scripting language that receives control when the event corresponding to the handler occurs. |
Event binding | The association of script with an event (on a document, window, or element). |
Now that you know what an event is, let's take a look at the events that are automatically generated using DHTML. An excellent article about the architecture of events is Bubble Power: Event Handling in Internet Explorer 4.0. If you are already proficient with event-based programming, I heartily recommend reading this article. If you are just learning, you will want to save this link for later (but not much later -- you'll be an expert in no time). Finally, check out the book Inside Dynamic HTML by Scott Isaacs (ISBN# 1-57231-686-1). Chapter 3 covers the DHTML event model fully and should fill in any of the remaining blanks you might have. Scott's Web site, http://www.insideDHMTL.com/ , contains up-to-date information on DHTML.
If you aren't going to read the documentation (tsk, tsk, tsk), I'll give you a primer on events in the next section.
Here's a step-by-step description of the flow of events:
For example, let's say that you have a handler for a mouse click and your code looks something like this:
<HTML> <HEAD><SCRIPT LANGUAGE="JavaScript"> function wasClicked() { window.alert("I was clicked " + window.event.srcElement.tagName); } </SCRIPT> </HEAD> <BODY onclick="wasClicked()"> <H1>Welcome!</H1> <P>This is a very <B>short</B> document. </BODY> </HTML>
When the user clicks the mouse, the event is fired. The notification is created and the event handler, wasClicked, is called. Within this function, an alert (a pop-up window) is presented informing you which tag was clicked. The browser's Event object for the page has properties, such as the name of the tag, associated with it. In the code above, the name of the tag is accessed via the event object's window.event.srcElement.tagName property.
The Event object is available while the script that contains the element is running. If you want to get information about what key was pressed or where the mouse is, you need to create an event handler in your script to trap those events and retrieve the information about the element on which the event has occurred (the srcElement). You retrieve the information about an element through the event's properties. All event properties are available to all events; however, not all properties are useful for all events. For example, the altKey property really only makes sense for a key-press event. Or, to put it in more human terms, let's say that you are late for work and you have decided to bend the rules a bit about how fast you should go. Invariably, you are stopped by a police officer. On the speeding ticket, one of the items listed would be how fast you were going. The miles per hour would then be a property of the event (speeding).
The following table lists the event properties that are supported. Full documentation on the Event object can be found in the Internet Client SDK.
Table 1. Event Properties
Property | Description |
AltKey | The state of the ALT key: TRUE if down, FALSE otherwise. |
Button | Which mouse button is pressed. |
CancelBubble | Stops events from bubbling up the parent hierarchy. |
ClientX | X position of the mouse within the client window. |
ClientY | Y position of the mouse within the client window. |
CtrlKey | The state of the CTRL key: TRUE if down, FALSE otherwise. |
FromElement | Which element the mouse was on during an onmouseover or onmouseout event. |
KeyCode | Which (Unicode) key was pressed. |
OffsetX | X position of the mouse relative to the current container. |
OffsetY | Y position of the mouse relative to the current container. |
Reason | Used on a data source object to give the reason for completion of the data transfer. |
ReturnValue | The return value from the event. |
ScreenX | X position relative to the screen size. |
ScreenY | Y position relative to the screen size. |
ShiftKey | The state of the SHIFT key: TRUE if down, FALSE otherwise. |
SrcElement | The element that fired the event. |
SrcFilter | The filter object that caused the onfilterchange event to fire. |
ToElement | Which element the mouse moved to during an onmouseover or onmouseout event. |
Type | The event name. |
X | X position relative to the parent hierarchy; positioned using CSS positioning. |
Y | Y position relative to the parent hierarchy; positioned using CSS positioning. |
As I mentioned earlier, when an event is fired, it is passed up the parent hierarchy until either the event forwarding is cancelled (this is known as cancelling the bubble) or until you get to the top of the parent chain (the document). In the code below (shamelessly pilfered from the Internet Client SDK), you see a very simple script that has two handlers for mouse clicks: one is attached to the <BODY> and one to the <P>. Running this code demonstrates the parent/child relationship of document elements. Clicking on the word "very" will produce two pop-ups: first, "You clicked me P," then "I was clicked P." The handler wasAlsoClicked is called first, then the event goes up the parent chain and the wasClicked handler is called.
<HTML> <HEAD><SCRIPT LANGUAGE="JavaScript"> function wasClicked() { alert("I was clicked " + window.event.srcElement.tagName); } function wasAlsoClicked() { alert("You clicked me " + window.event.srcElement.tagName); } </SCRIPT> </HEAD> <BODY onclick="wasClicked()"> <H1>Welcome!</H1> <P onclick="wasAlsoClicked()">This is a very <B>short</B> document. </BODY> </HTML>
Now that you've seen how events move up the parent chain, how do you stop an event from bubbling up the parent chain? You can do this by setting the cancelBubble property on the event. The example below (also from the Internet Client SDK -- do you get the feeling you should download this SDK?) demonstrates what happens when you cancel an event. If you run the example below and click on the <H1> text, "Welcome," the heading will turn green. If you click on the <P> text, "This is a very short document," the text will be underlined. If the bubble was not cancelled, the parent item would also be underlined.
<HTML> <HEAD><SCRIPT LANGUAGE="JavaScript"> function setBodyStyle() { // Set all headings to green var coll = document.all.tags("H1"); for (i=0; i<coll.length; i++) coll.item(i).style.color = "green"; } function setParaStyle() { // Underline the paragraph var el = window.event.srcElement; while ((el != null) && (el.tagName != "P")) { el = el.parentElement; } if (el != null) el.style.textDecoration = "underline"; window.event.cancelBubble = true; } </SCRIPT> </HEAD> <BODY onclick="setBodyStyle()"> <H1>Welcome!</H1> <P onclick="setParaStyle()">This is a very <B>short</B> document. </BODY> </HTML>
I've given you an example that demonstrates how you can cancel bubbling. Now let's look at an example that demonstrates how to cancel the default action.
<HTML> <HEAD><SCRIPT LANGUAGE="JavaScript"><!-- function confirmDefault() { sMsg = "Do you want to go to " + window.event.srcElement.innerText + "? "; if (!window.confirm(sMsg)) { window.event.returnValue = false; } } //--></SCRIPT> <TITLE></TITLE> </HEAD> <BODY> <A HREF="http://www.microsoft.com/sitebuilder/" ONCLICK="confirmDefault()"> <P>MSDN Online Home Page</A> </P> </BODY> </HTML>
In the script above, you can see that the OnClick handler is created to confirm whether the user will go to the site listed. If the user clicks the Cancel button, the default action (navigating to the link) is cancelled.
You should now have a pretty good idea of event basics with DHTML. For detailed information, refer to the Internet Client SDK under Dynamic HTML. The documentation provides not only information about how to use DHTML, but also interactive samples. Another good source for information is the MSDN Online (MSDN Online). There is a section devoted to DHTML as well as a regular MSDN Online Voices column.