View Full Version : expando context "this" discrepancy in IE

03-05-2005, 08:34 PM
Inside an expando event handler, "this" is always a reference to the object:

someDiv.onmousedown = function()
//"this" is a reference to someDiv


So by extension:

someDiv.addEventListener('mousedown', function()
//"this" is a reference to someDiv

}, false);

However in IE:

someDiv.attachEvent('onmousedown', function()
//"this" is a reference to window


Have I got that right, is that what always happens? Or have I encountered an anomoly within the script I'm using it?

03-05-2005, 09:15 PM
If you are calling someDiv.attachEvent, then you can use the identifer "someDiv" within the function you are passing to attachEvent.

03-05-2005, 09:22 PM
ta :thumbsup:

03-05-2005, 09:28 PM
Oh ... no, that's not going to work .. because the "someDiv" reference is actually "this.elements[i]", and even though I have a parent-"this" reference created as "self = this", so I can go "self.elements[i]" - it doesn't come out as the element I want, it comes out as that element's nth element (depending on the residual value of i from the constructing loop)

Phew ... nevermind - I have an alternative hack:

//convert event argument
if(!e) { e = window.event; }

//if "this" is a reference to window (IE)
if(this == window)
//iterate upwards from the event target
//until we find a reference to the box
var tmp = e.srcElement;
var parent = tmp.parentNode;
tmp = parent.parentNode;

//otherwise copy this to tmp
else { tmp = this; }

Not the most elegant ... but it will have to do for now.

Cheers anyway :thumbsup:

03-05-2005, 10:50 PM
this contains the global object in all cases where the function is not called as a method of an object. The DOM0 event handlers worked through method calls.

addEventListener if implemented according to the rules for function calls laid forth by the ECMAScript 3 specification, uses function callbacks and not method calls and similarly goes for attachEvent. (Specifically for the reason that using method calls disallow multiple event listeners...) Thus, if the ECMAScript implementation is reasonably conformant, this SHOULD point to the global object, not doing so would be an error. For W3C DOM events, the Event.prototype.currentTarget property should contain a reference to the element which originally dispatched the event, which means that it should be the same as this for a DOM0 event.

Sadly, the Microsoft model only has Event.prototype.srcElement which is equivalent to Event.prototype.target and not any equivalent to Event.prototype.currentTarget.

From previous testing, I know that there are W3C DOM implementations (though I can't recall exactly which browsers, it was a while ago I tested this) that act like they are callbacks as they should, and there are those that act like they were method calls, so you shouldn't rely on this pointing to the dispatching node unless you are actually using the DOM0 event mechanism.

Edited to take some things discussed in DOM Event Scripting, (undocumented) Tip #1: DOM2 Events and Internet Explorer into account, and for correctness.

03-07-2005, 08:18 PM
Righto .. I'll use upward iteration from target for everyone then. Cheers :)