[ Team LiB ] Previous Section Next Section

9.6 Determining Which Element Received an Event

NN 6, IE 4

9.6.1 Problem

You want to obtain a reference to the element receiving the most recent event.

9.6.2 Solution

The IE and W3C DOM event models offer properties of their respective event objects that return a reference to the element initially receiving an event. Although the syntax is different, you can equalize IE's srcElement and the W3C DOM's target event properties to achieve a single reference valid in both browsers. The technique also requires equalizing the event objects, as shown in Recipe 9.1.

A typical event handler function that degrades gracefully in older browsers starts this way:

function myFunction(evt) {
    evt = (evt) ? evt : ((window.event) ? event : null);
    if (evt) {
       var elem = (evt.target) ? evt.target : 
          ((evt.srcElement) ? evt.srcElement : null);
       if (elem ) {
           // perform all event processing here
       }
    }
}

9.6.3 Discussion

The W3C DOM event model, as implemented in Netscape 6 or later, presents one extra wrinkle to the solution if the target element acts as an HTML container of one or more text nodes. In the W3C DOM, text nodes can be targets. Therefore, if you bind an onclick event handler to an a element that surrounds hyperlinked text, the event object passed to the handler function regards the text node nested inside the a element as the target. More than likely, however, your function is interested in the surrounding a element and its properties. If the elements you're assigning events to are containers, and if your function must obtain a reference to the element containing that text, modify the template shown in the Solution to the following:

function myFunction(evt) {
    evt = (evt) ? evt : ((window.event) ? event : null);
    if (evt) {
       var elem = (evt.target) ? evt.target : 
          ((evt.srcElement) ? evt.srcElement : null);
       if (elem.nodeType =  = 3) {
           elem = elem.parentNode;
       }
       if (elem) {
           // perform all event processing here
       }
    }
}

Not all event functions need a reference to the target element, but the technique is important if you are using event handler property binding techniques for elements that normally need some kind of connection to the context of the event. For example, say you assign an onchange event handler to a text input field through property syntax such as:

document.getElementById("emailAddress").onchange = validateEmail;

In this case, the function needs to get information from the element to complete its job. In the following fragment, the value and form properties of a text input box are retrieved as properties of the target element:

function validateEmail(evt) {
    evt = (evt) ? evt : ((window.event) ? event : null);
    if (evt) {
       var elem = (evt.target) ? evt.target : 
          ((evt.srcElement) ? evt.srcElement : null);
       if (elem.nodeType =  = 3) {
           elem = elem.parentNode;
       }
       if (elem) {
           var val = elem.value;
           var form = elem.form;
           // perform more event processing here
       }
    }
}

If you are scripting for a purely W3C DOM event model environment, you can also take advantage of the combination of event propagation and the currentTarget property. This property returns a reference to the node that is bound to the event handler function processing the event. For example, in the case of the a element surrounding a text node, you can bind the event handler to the a element, and then use the currentTarget property to get the reference to the a element, even though the child text node is the initial target of the click event:

function handleLinkClick(evt) {
    var elem = evt.currentTarget;
    // process event on the <a> element here
}

Get to know these techniques of reading the event object for information about the target element. As the trend continues to move away from in-tag event handler binding, the element reference becomes increasingly important for effective event handler functions.

9.6.4 See Also

Recipe 9.1 for equalizing IE and W3C DOM event objects in event handler functions.

    [ Team LiB ] Previous Section Next Section