Hitch. Object-oriented event handlers with jQuery

Moving to jQuery from YUI has been a 99% positive experience. Probably the only thing I’ve really missed was the ability provided by YUI Event to control the object scope that an event handler was executed in.

When you attach an event to an element in jQuery within the event handler function the this keyword always refers to the element that triggered the event.

$('a').bind('click', function() {
    alert(this);
});```

Here this will be the a element that triggered the event. For the majority of the time this behaviour is absolutely ideal. However, if you’re using object oriented javascript and are trying to handle an event using a method of one of your classes, the chances are you’d want this to refer to the instance of your class instead of the DOM element.

var Klass = function() {
this.message = 'hello';
};
Klass.prototype.handleClick = function(e) {
alert(this.message);
};
var obj = new Klass();

$('a').bind('click', obj.handleClick);```

The above fails because when Klass.prototype.handleClick is triggered from the click event this still refers to the a element that was clicked on. Hence this.message is undefined.

To solve this problem I made a small jQuery plugin called hitch that allows you to control the object scope. The above example would be rewritten as

var Klass = function() {
    this.message = 'hello';
};
Klass.prototype.handleClick = function(e) {
    alert(this.message);
};
var obj = new Klass();

$('a').hitch('click', obj.handleClick, obj);```

If the handleClick method needs to access the DOM element that triggered the event, that can still be accessed through e.target. If the object scope argument is omitted then hitch should work in the same way as the standard bind method.

The plugin itself is just a few lines

(function($) {
$.fn.hitch = function(ev, fn, scope) {
return this.bind(ev, function() {
return fn.apply(scope || this, Array.prototype.slice.call(arguments));
});
};
})(jQuery);```

I believe similar functionality is scheduled to be included in an upcoming jQuery release, but for the time being I’m finding this plugin to be exceptionally useful.