How to keep some context attached to a JavaScript event handler?
The problem is the following... You want to attach a handler to a DOM event but you want some information to remain associated with it. Let's say for example that the handler is a method of an object that makes use of the "this" pointer somewhere in its body (as it should, otherwise it should probably be static). As the API to attach a handler just takes a function pointer, and the "this" pointer is determined by the DOM element that triggered the event, it seems difficult to do. The Microsoft Ajax Library (like almost all Ajax libraries, let's be honest) provides an easy way to work around that. If you call:
var myDelegate = Function.createDelegate(this, this.myHandler);
then myDelegate will contain a reference to the this.myHandler function within which "this" will always mean the same thing as when you called createDelegate. For those of you who want to know how this works, feel free to look at the code. It's actually a simple application of closures.
We also have a variant of this that associates arbitrary context (not just the meaning of "this") with a function pointer. You can think of it as a differed execution of a function where the parameters are determined in advance:
var myCallback = Function.createCallback(myHandlerFunction, {foo: "bar"});
The callback function that this command creates can be called without any arguments but it will remember the argument that was passed in when the callback was created. For example, if the function body is:
function myHandlerFunction(p) {
alert(p.foo);
}
Then calling myCallback() will display an alert with "bar" as the message. Now if you want to use this as an event handler and hook it some HTML element, you have to know that the function will be called with the DOM event object as the first parameter and your context parameter will be demoted to second parameter:
function myHandlerFunction(e, p) { // DOM event handler here
alert(e.target.tagName + " raised an event with parameter " + p.foo);
}
But if you're building a component and all you want to do is hook up a bunch of DOM events to instance methods where you use the "this" pointer to refer to your component instance, the easiest way is probably to use $addHandlers (don't forget to also call $clearHandlers from dispose...):
$addHandlers($get("myElement"), { click: this._onclick, focus: this._onfocus, blur: this._onblur }, this);
This will create the delegates to _onclick, _onfocus and _onblur for you and attach them to the click, focus and blur events of myElement. That's a great helper if you're developing controls or behaviors.
There are a few more complex things that you can do with createCallback and createDelegate but that should give you the essential information. Feel free to ask questions in the comments section if you want to know more.
UPDATE: I forgot to mention that those techniques, beyond being quite common in JavaScript/DHTML, are closely related to "currying": http://en.wikipedia.org/wiki/Currying
UPDATE 2: I made the DOM event case a little clearer and included an example of that.