On 09/06/2005 22:21, philmaker wrote:
I've also struggled with this for a bit and think I've found the best
solution to achieve OO 'this' keyword re-entry from an event handler.
There are numerous ways, and the best depends solely on current
requirements.
[snip]
function EventManager() {
this.registerClickEvent = EventManager_RegisterClickEvent;
}
If registerClickEvent is the only property, then EventManager would be
better as an object:
var EventManager = {
registerClickEvent : function(...) {
...
}
};
function EventManager_RegisterClickEvent(element, object, func) {
var f = function() {
func.apply(object);
};
Or:
function f() {
func.call(object);
}
if (element.attachEvent) {
element.attachEvent("onclick", f);
} else {
element.addEventListener("click", f, false);
}
}
This isn't good in general for a couple of reasons:
1. As the inner function, f, will survive after registerClickEvent is
called, it will form a closure that keeps all of the arguments to
the outer function in memory. In IE, this will cause a memory leak
because element is a DOM object and not subject to JScript's
garbage collection mechanism.
2. Both the Function.prototype.apply and .call methods are late
additions to JScript. Versions prior to 5.5 (therefore usually
IE 5.5, too) do not implement them, so the inner function will
cause a run-time error when called.
3. If a browser doesn't support the attachEvent method, it doesn't
automatically mean it supports the addEventListener method. Indeed,
some user agents will support neither, but can have function
references assigned to event properties. As the attachEvent
mechanism doesn't set the this operator correctly, it is usually
better to avoid using it.
Many of the regulars, myself included, have posted code that will add
multiple listeners to an element, and avoid issues (1) and (3).
Emulation to avoid issue (2) is just as abundant.
As most listeners aren't useful as public methods, a variation of
Lasse's suggestion will usually do:
function MyObject() {
var self = this;
function listener() {
/* Use self to refer to the object instance and
* the this operator to refer to the element.
*/
}
this.attach = function(element) {
/* Using the addEventListener method for simplicity. */
element.addEventListener('click', listener, false);
};
}
Mike
--
Michael Winter
Replace ".invalid" with ".uk" to reply by e-mail.