WebReference.com - Part 2 of chapter 5 from Creating Applications with Mozilla. From O'Reilly (2/5).
[previous] [next] |
Creating Applications with Mozilla, Chapter 5: Scripting Mozilla
Events and the Mozilla Event Model
The event model in Mozilla is the general framework for how events work and move around in the user interface. As you've already seen, events tend to rise up through the DOM hierarchy-a natural process referred to as event propagation or event bubbling. The next two sections describe event propagation and its complement, event capturing.
Event propagation and event bubbling
This availability of events in nodes above the element of origin is known as event propagation or event bubbling. Event bubbling means you can handle events anywhere above the event-raising element in the hierarchy. When events are handled by elements that did not initiate those events, you must determine which element below actually raised the event. For example, if an event handler in a menu element handles an event raised by one of the menu items, then the menu should be able to identify the raising element and take the appropriate action, as shown in Example 5-7. In this example, a JavaScript function determines which menuitem
was selected and responds appropriately.
Example 5-7: Event propagation
<script type="application/x-javascript">
function doCMD(el) {
v = el.getAttribute("label")
switch (v) {
case "New":
alert('New clicked');
break;
case "Open":
alert('Open clicked');
break;
case "Close":
alert('Close clicked');
break;
}
}
</script>
...
<menu class="menu" label="File" oncommand="doCMD(event.target)">
<menupopup>
<menuitem label="New" />
<menuitem label="Open" />
<menuitem label="Close" />
</menupopup>
</menu>
The event handler in the parent node menu finds out which child menuitem
was actually clicked by using event.target
and takes action accordingly. Let's walk through another possible scenario. If a user of an application selects an item from a menu list, you could get the node of that item by using event.target
. Your script could then abstract that item's value or other information, if necessary.
Trapping events
When an event is raised, it is typically handled by any node interested in it as it continues its way up the DOM hierarchy. In some cases, you may want to handle an event and then prevent it from bubbling further up, which is where the DOM Event method stopPropagation( )
comes in handy.
Example 5-8 demonstrates how event bubbling can be arrested very simply. When the XUL document in Example 5-8 loads, an event listener is registered with a row
in the tree. The event listener handles the event by executing the function stopEvent( )
. This function calls an event object method, stopPropagation
, which keeps the event from bubbling further up into the DOM. Note that the tree itself has an onclick
event handler that should display a message when clicked. However, the stopEvent( )
method has stopped propagation, so after the data in the table is updated, the event phase is effectively ended. In this case, the function was used to trap the event and handle it only there.
Example 5-8: stopPropagation( ) event function
<?xml version="1.0"?>
<!DOCTYPE window>
<window id="test-win"
xmlns="https://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
orient="vertical"
onload="load( );">
<script type="application/x-javascript">
function load( ) {
el = document.getElementById("t");
el.addEventListener("click", stopEvent, false);
}
function stopEvent(e) {
// this ought to keep t-daddy from getting the click.
e.stopPropagation( );
}
</script>
<tree>
<!-- tree columns definition omitted -->
<treechildren flex="1" >
<treeitem id="t-daddy"
onclick="alert('t-daddy');" // this event is never fired
container="true" parent="true">
<treerow id="t">
<treecell label="O'Reilly" id="t1" />
<treecell label="https://www.oreilly.com" id="t2" />
</treerow>
</treeitem>
</treechildren>
</tree>
</window>
Capturing events
Event capturing is the complement of event bubbling. The DOM provides the addEventListener
method for creating event listeners on nodes that do not otherwise supply them. When you register an event listener on an ancestor of the event target (i.e., any node above the event-raising element in the node hierarchy), you can use event capturing to handle the event in the ancestor before it is heard in the target itself or any intervening nodes.
To take advantage of event capturing (or event bubbling with elements that do not already have event listeners), you must add an event listener to the element that wants to capture events occurring below it. Any XUL element may use the DOM addEventListener
method to register itself to capture events. The syntax for using this method in XUL is shown here:
XULelement = document.getElementById("id of XULelement");
XULelement.addEventListener("event name", "event handler code",
useCapture bool);
The event handler code argument can be inline code or the name of a function. The useCapture
parameter specifies whether the event listener wants to use event capturing or be registered to listen for events that bubble up the hierarchy normally. In Figure 5-3, the alert dialog invoked by the menuitem
itself is not displayed, since the root window
element used event capture to handle the event itself.
An onload
event handler for a XUL window can also register a box
element to capture all click events that are raised from its child elements:
var bbox = document.getElementById("bigbox");
if (bbox) {
bbox.addEventListener("click", "alert('captured')", true);
}
...
<box id="bigbox">
<menu label="File">
<menupopup>
<menuitem label="New" onclick="alert('not captured')" />
...
<menupopup>
</menu>
</box>
[previous] [next] |
Created: September 26, 2002
Revised: September 26, 2002
URL: https://webreference.com/programming/javascript/mozillaapps/chap5/2/2.html