Routing Events: Avoiding Bubble Bobble (Microsoft)
February 15,1999
Adjusting to Microsoft's event bubbling paradigm may
take some getting used to, especially for those weaned
on Netscape's event model which has been around longer.
Be especially attentive when nesting event handlers such
as MouseOver and MouseOut. Because every
MouseOver onto a particular element necessarily means
a MouseOut from another, and each of these events
will by default bubble up through the element hierarchy,
it is easy to launch a cascade of bubbling events triggering
all sorts of unwanted event handlers.
Two event object properties which help reduce confusion
are srcElement and toElement. These properties
provide a peek into which elements are connected to a
particular event, allowing for the possibility of cancelling
bubbling under certain conditions.
The srcElement property is an object reflecting
the element which triggered the event. Poking at the
id property of srcElement reveals any name
attached to the element via the id attribute of its tag.
The outerHTML property reveals the entire HTML
tag which created the element. Either can be used to identify
the triggering element.
<div id="div1" onClick="alert('Div1 clicked');">
Greetings
<div id="div2" onClick="alert('Div2 clicked');
if (event.srcElement.id=='para1')
{event.cancelBubble=true};">
<p id="para1">I am strong.</p>
<p id="para2">I am tall.</p>
</div>
</div>
|
If para1 is clicked the event bubbles up to div2. The
onClick event handler for div2 pops up a message
and then evaluates the source for this event. If the
source turns out to be the element named "para1"
then event bubbling is cancelled; otherwise bubbling is
allowed to continue. Thus, if para2 is clicked, following
the "Div2 clicked" message the event would bubble
up to div1 and trigger the "Div1 clicked"
message.
The toElement property is intended for use with
an onMouseOver or onMouseOut event. These
events can become confusing because they trigger each
other -- here is a simple example with only the onMouseOver
event employed.
<div id="div1" onMouseOver="alert('Over Div1');">
Greetings
<div id="div2" onMouseOver="if(event.toElement.id=='para1')
{event.cancelBubble=true};">
<p id="para1" onMouseOver="alert('Strong!');">I am strong.</p>
<p id="para2" onMouseOver="alert('Tall!');">I am tall.</p>
</div>
</div>
|
If the mouse moves over para1 the message "Strong!"
pops up. This MouseOver event then bubbles
up to div2 which tests to see if the original destination of
this event was para1. If yes then bubbling is cancelled
and nothing more happens. If the mouse were to move over para2,
though, the message "Tall!" pops up.
This MouseOver event bubbles up to div2 which sees
that it was not para1. Bubbling thus continues up to
div1 which receives the MouseOver and triggers its
own event handler, popping the message "Over Div1".
Constructing event code in the Microsoft environment can be
tricky with all this bubbling going on -- it may
be tough to write code which works perfectly the first time
but being aware of how event bubbling works should
make it easy to debug strange behaviors which occur as a
by-product of bubbling.
Additional Resources
Routing Events: Event Bubbling (Microsoft)
Events in JavaScript: An Inside Look
|