Who Caught Me?: The JavaScript techniques which do and don't work (for IE, Windows) in finding out which object caught a bubbled event.
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. |