Skip to main content

Bug Tracker

Side navigation

#12031 closed feature (migrated)

Opened July 06, 2012 03:31PM UTC

Closed October 20, 2014 11:49PM UTC

Allow objects as event handlers

Reported by: petka_antonov@hotmail.com Owned by: dmethvin
Priority: low Milestone: 1.12/2.2
Component: event Version: 1.7.2
Keywords: Cc:
Blocked by: Blocking:
Description

Doing OOP with jQuery events requires a lot of $.proxy boilerplate. the .addEventListener interface allows passing

an object as a handler like so:

function SomeWidget( elem ) {
	this.elem = elem;
}

SomeWidget.prototype = {
	constructor: SomeWidget,

	renderTo: function( target ) {
		$(target).append(this.elem);
		this.elem.addEventListener( "click", this );
		this.elem.addEventListener( "mousemove", this );
	},

	mousemove: function( e ) {

	},

	click: function( e ) {

	},

	handleEvent: function( e ) {
		return this[e.type].apply( this, arguments );
	}
};

With jQuery you have to do this:

function SomeWidget( elem ) {
	this.elem = elem;
	//Each method needs to be bound to the instance. This also has overhead of creating many functions.
	this.mousemove = $.proxy( this.mousemove, this );
	this.click = $.proxy( this.click, this );
}

SomeWidget.prototype = {
	constructor: SomeWidget,

	renderTo: function( target ) {
		$(target).append(this.elem);
		$(this.elem).on( {
			click: this.click,
			mousemove: this.mousemove
		});
	},

	mousemove: function( e ) {

	},

	click: function( e ) {

	}
};

With jQuery supporting objects as event handlers, it would work like:

function SomeWidget( elem ) {
	this.elem = elem;
}

SomeWidget.prototype = {
	constructor: SomeWidget,

	renderTo: function( target ) {
		$(target).append(this.elem);
		$(this.elem).on( "click mousemove", this );
	},

	mousemove: function( e ) {

	},

	click: function( e ) {

	},

	handleEvent: function( e ) {
		return this[e.type].apply( this, arguments );
	}
};

And that's it. No $.proxy hacks, no redundant creation of functions just to retain binding.

Attachments (0)
Change History (16)

Changed July 13, 2012 03:13AM UTC by dmethvin comment:1

status: newopen

Worth thinking about so I'll leave it open.

Changed July 13, 2012 03:14AM UTC by dmethvin comment:2

component: unfiledevent

Changed July 13, 2012 03:27AM UTC by rwaldron comment:3

_comment0: I'm into this \ \ http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventListener1342150112997297

I'm into this

http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-EventListener

@dmethvin - if you don't mind, I'd like to prototype this one :)

Changed July 13, 2012 02:40PM UTC by rwaldron comment:4

owner: → rwaldron
status: openassigned

Changed July 13, 2012 02:43PM UTC by rwaldron comment:5

note to self...

 .on({ click: fn }) 

Has to support handling:

// delegated events
.on({ click: fn }, "div");

// data object events
.on({ click: fn }, "div", dataobject);

Changed September 09, 2012 01:11AM UTC by dmethvin comment:6

type: enhancementfeature

Bulk change from enhancement to feature.

Changed September 10, 2012 01:01PM UTC by mikesherov comment:7

priority: undecidedlow

Changed September 12, 2013 03:17PM UTC by gnarf comment:8

owner: rwaldrongnarf

Changed September 17, 2013 02:02PM UTC by dmethvin comment:9

gnarf and I talked about this in Austin. It would be a very low-level public interface, ideally the current event features would be built on top of it. Essentially replace this function so we don't go to the current jQuery dispatcher and instead use a caller-supplied dispatching object. That would provide users with low-overhead ways to handle high-frequency events like scroll or mousemove (or the upcoming pointermove) by avoiding jQuery.event.fix() for example.

Changed September 18, 2013 02:10PM UTC by gibson042 comment:10

A good implementation would make something like https://github.com/jquery/jquery/pull/1367/files significantly more lightweight.

Changed February 12, 2014 12:06AM UTC by dmethvin comment:11

owner: gnarfdmethvin

Changed March 04, 2014 02:31PM UTC by dmethvin comment:12

milestone: None1.12/2.2

Changed April 02, 2014 02:43AM UTC by dmethvin comment:13

Additional note re #14953, can we have a way to do capturing here? As I understand the .addEventListener interface it seems like all the events in the attached object would be capturing.

Changed April 02, 2014 01:49PM UTC by petka_antonov@hotmail.com comment:14

In addEventListener the optional useCapture parameter defines whether capturing is in use regardless if you use a function or an object as a handler. The default is false so in the example all events are bubbling.

Changed July 11, 2014 01:54PM UTC by dmethvin comment:15

Re rwaldron's comment 5 above, I am thinking this interface will be low level enough that we will not support any type of enhancement. That includes special events, delegation, fixing, or additional data. To get those things you'll either need to do them yourself or use the standard interfaces.

For the additional data issue, it's probably not an issue since the this points to an object you get to populate. The other features cost execution time and one of the reasons for this interface is to provide a clean way to get performance when you don't need things like event normalization across browsers.

Changed October 20, 2014 11:49PM UTC by m_gol comment:16

resolution: → migrated
status: assignedclosed