The Navigator Event Model: Dropping Events - Doc JavaScript | WebReference

The Navigator Event Model: Dropping Events - Doc JavaScript


Dropping Events

If you call the routeEvent() function within an event processing function, the browser looks for other event handlers for the event. If another object (e.g., document, layer) is trying to capture the event, its event processing function is called. If no other event handler is trying to capture the event, the event drops further down the hierarchy to the event's intended target (e.g., a button, a link). The routeEvent() function returns the value returned by the next event handler that captured the event (if it exists). If there are no event handlers in the hierarchy that are attempting to capture the event, the function returns a false value (undefined, null).

An event falls down towards its intended target (the one that generated it). It does not reach event handlers that are not in its path. For example, if you click a link, and invoke the routeEvent() function from within the window object's event processing function, the event drops down to the document object. If the document object doesn't feature an event handler (document.onclick) that captures that type of event (click), the event proceeds to the link itself, which is the last object that has the opportunity to capture the event. If the link doesn't have the required event handler, the event simply evaporates, and the routeEvent() function returns a false value.

If routeEvent() calls an event handler whose function is to display a new page, the action takes place without returning to the capturing object. Take a look at the following HTML documents:

main1.html

<HTML>
<HEAD>
<TITLE>Main Document #1</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!--
function mainProcessLinks(e) { 
  alert("The event was captured in the main document.")
}
document.captureEvents(Event.CLICK);
document.onclick = mainProcessLinks;
// -->
</SCRIPT>
</HEAD>
<BODY>
<ILAYER NAME="sub" SRC="sub1.html"></ILAYER>
<FORM>
The button in the main document:
<INPUT TYPE="button" NAME="mainButton"
       VALUE="Main Button" onClick="alert(this.name)">
</FORM>
</BODY>
</HTML>

sub1.html

<HTML>
<HEAD>
<TITLE>Layer Document #1</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!--
function layerProcessLinks(e) { 
  alert("The event was captured in the layer document.")
}
document.captureEvents(Event.CLICK);
document.onclick = layerProcessLinks;
// -->
</SCRIPT>
</HEAD>
<BODY>
<FORM>
The button in the layer document:
<INPUT TYPE="button" NAME="layerButton"
       VALUE="Layer Button" onClick="alert(this.name)">
</FORM>
</BODY>
</HTML>

Click here to open main1.html in a new window. The second document, sub1.html, is used as a layer in the first document. Since the layer and the main window have independent document objects, they each provide a different event processing function to handle click events. However, the main document's document object contains the layer's document object, so its event processing function captures the click events for both buttons.

When you click the button in the main window, the mainProcessLinks() is invoked. Even when you click the other button, in the layer, the main window's mainProcessLinks() function is invoked. Since it doesn't send the event to the button with the handleEvent() method, and doesn't drop it down the hierarchy with the routeEvent() function, it doesn't reach the button that generated the event. Therefore, the statement (alert(this.name)) in the button's event handler (both buttons) is never executed. Furthermore, even if you click the layer's button, the event doesn't reach the layer's document object, because the event is captured (and trapped) at a higher level. The following diagram illustrates the object hierarchy for this example:

  1. The main window's document:
    document
    1. The layer's document:
      document.sub.document
      1. The layer's button:
        document.sub.document.forms[0].layerButton
    2. The main window's button:
      document.forms[0].mainButton

Take a look at the following example, which puts the routeEvent() function to work:

main2.html

<HTML>
<HEAD>
<TITLE>Main Document #2</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!--
function mainProcessLinks(e) {
  var strTarget = " " + e.target;
  if (strTarget.indexOf("Button") > 0) {
    alert("The event was captured in the main document.")
    routeEvent(e);
  }
}
document.captureEvents(Event.CLICK);
document.onclick = mainProcessLinks;
// -->
</SCRIPT>
</HEAD>
<BODY>
<ILAYER NAME="sub" SRC="sub2.html"></ILAYER>
<FORM>
The button in the main document:
<INPUT TYPE="button" NAME="mainButton"
       VALUE="Main Button" onClick="alert(this.name)">
</FORM>
</BODY>
</HTML>

sub2.html

<HTML>
<HEAD>
<TITLE>Layer Document #2</TITLE>
<SCRIPT LANGUAGE="JavaScript">
<!--
function layerProcessLinks(e) { 
  alert("The event was captured in the layer document.")
  routeEvent(e);
}
document.captureEvents(Event.CLICK);
document.onclick = layerProcessLinks;
// -->
</SCRIPT>
</HEAD>
<BODY>
<FORM>
The button in the layer document:
<INPUT TYPE="button" NAME="layerButton"
       VALUE="Layer Button" onClick="alert(this.name)">
</FORM>
</BODY>
</HTML>

Click here to open main2.html in a new window. If you click the layer's document button, its click event is captured by the document object of the main window (main2.html). For the event to reach the intended target, the main document's function must instruct the event what to do next, via the routeEvent() function. The event then continues downward through the object hierarchy on its way to the intended target. During its journey, the event is captured by the layer's document object (which is set to catch such events). For the event to continue to the button, the layer's event processing function, layerProcessLinks(), must also let it go with the routeEvent() method. Once the event reaches its intended target, the event goes no further.

If you click the main document's button, the event doesn't reach the layer's window or document object, because the layer is not a parent of the main window's button. They're at the same level. Therefore, the event goes directly from the main window's mainProcessLinks() function to the button itself. The button's event handler script is then executed.

Notice how we avoid a click event outside the buttons. As we'll explain later in this column, the event object's target property references the object for which the event is intended. Since we are interested only in button's events, we only handle events which their target property includes the "Button" substring. We first convert the target property to a string and then check for the existence of the "Button" substring. We just ignore the event if it is not intended for a button:

  var strTarget = " " + e.target;
  if (strTarget.indexOf("Button") > 0) {
    alert("The event was captured in the main document.")
    routeEvent(e);
  }

Like the handleEvent() method, routeEvent() returns the value that is returned by the event handler of the next object that captures the event. In the next section of this column we'll explain what the e parameter is, what it does, and how you should use it.

http://www.internet.com


Created: December 16, 1997
Revised: July 12, 1998

URL: http://www.webreference.com/js/column9/drop.html