Who Caught Me?: The JavaScript techniques which do and don't work (for IE, Windows) in finding out which object caught a bubbled event.

posted 2002-Jan-18

This article has been archived due to outdated information or poor advice. Read on at your own risk.

Summary

In client-side JavaScript, if you want to refer to the object who caught a bubbled event in an event-handling function, the following techniques all work…

<div id="foo" onclick="alert(<b>this</b>.outerHTML)"><b>This bold</b> won't interfere.</div>
<div id="foo"><b>This bold</b> won't interfere.</div>

foo.onclick=SayMyName;
foo.onclick=function(){SayTheNameOf(this)});
foo.onclick=function(){SayTheNameOf(foo)});
foo.attachEvent('onclick',function(){SayTheNameOf(foo)});

function SayMyName(){ alert(this.outerHTML) }
function SayTheNameOf(obj){ alert(obj.outerHTML) }

…but the following two do not work:

foo.attachEvent('onclick',SayMyName);
foo.attachEvent('onclick',function(){SayTheNameOf(this)});

Details

When event bubbling filters a user’s action through various superfluous layers, I often want to know which object caught the event (as opposed to which top-level element got in the way). For example, suppose I want to be able to drag a particular <div> around:

<div class="draggable" onmousedown="StartDragging()">
        It is <b>easy to drag</b> with the mouse.
</div>
<pre><code><div onmousedown="StartDragging()">
        It is <b>easy to drag</b> with the mouse.
</div>
…
function StartDragging(){
        var objectToDrag=event.srcElement;
        alert("I'm going to drag:\n"+objectToDrag.outerHTML);
        …
}

The above does not work because event.srcElement refers to the <b> tag if I click on the words “easy to drag”. The correct way to fix this is:

<div class="draggable" onmousedown="StartDraggingObject(this)">
        It is <b>easy to drag</b> with the mouse.
</div>
<pre><code><div onmousedown="StartDraggingObject(this)">
        It is <b>easy to drag</b> with the mouse.
</div>
...
function StartDraggingObject(objectToDrag){
        alert("I'm going to drag:\n"+objectToDrag.outerHTML);
        ...
}

Frequently I want to be able to attach an event handler programmatically (e.g. when I don’t have control over the source HTML). However, often I want to use the .attachEvent() method, to ensure I don’t run over any existing handlers.

Only one of the below works (creating an anonymous function and passing the object to it):

attachsimplefunction2.attachEvent('onmousedown',StartDraggingThis);
attachpassingthis2.attachEvent('onmousedown',function(){ StartDraggingObject(this) });
attachpassingobject2.attachEvent('onmousedown',function(){ StartDraggingObject(attachpassingobject2) });
Gavin Kistner
09:55AM ET
2003-Apr-21
The above was originally written and tested with IEWin. Although the above information has not been verified for other browsers, I do have a cross-browser (Mozilla/Netscape 6/IE/others) wrapper method for attaching events freely available.
Gavin Kistner
09:37AM ET
2003-Oct-17
I need to update this with proper DOM 2 Events information, using addEventListener and the correct evt.currentTarget element, which obviates the need for all this tomfoolery.
net.mind details contact résumé other
Phrogz.net