Skip to main content

Bug Tracker

Side navigation

#13864 closed feature (plugin)

Opened May 07, 2013 12:28PM UTC

Closed June 29, 2013 07:32PM UTC

Add onlyHandlers argument to trigger()

Reported by: adrian@planetcoding.net Owned by:
Priority: low Milestone: None
Component: event Version: 1.9.1
Keywords: Cc:
Blocked by: Blocking:
Description

Currently there are trigger and triggerHandler. However, the latter only works on the first element contained in the jQuery object so there is no way at all (besides calling $.event.trigger manually) to trigger bound events on a bunch of objects without executing the browser's default action.

For this reason I'm suggesting to add another argument to trigger:

	trigger: function( type, data, onlyHandlers ) {
		return this.each(function() {
			jQuery.event.trigger( type, data, this, onlyHandlers );
		});
	},

It would not break backwards compatibility and I can't imagine any other disadvantages in having that argument.

Attachments (0)
Change History (7)

Changed May 07, 2013 12:33PM UTC by scottgonzalez comment:1

...there is no way at all (besides calling $.event.trigger manually) to trigger bound events on a bunch of objects without executing the browser's default action.

There are actually multiple ways to do so, with public APIs. You can use .triggerHandler() inside .each() or you could create an event object using $.Event, call preventDefault() (and stopPropagation()), then pass that event object to .trigger().

Changed May 07, 2013 12:36PM UTC by adrian@planetcoding.net comment:2

True, but I'm sure you agree that neither of them are as nice as having an argument for this. A good example where the argument would be useful is a script for a "check all" button:

$('.checkboxes').prop('checked', true).trigger('click', null, true);

Sure, using the click event instead of change there is stupid but legacy code is widespread so being able to trigger events on all matched objects without the default executing would be useful. And using .each for such a simple one-liner (which is even still very readable) would not make the code cleaner, more beautiful or more readable.

Changed May 07, 2013 12:38PM UTC by scottgonzalez comment:3

I don't view .trigger('click', null, true); as beautiful or more readable. It's not at all clear what that does when looking at it. You need intimate knowledge of the API to be able to read that code.

Changed May 07, 2013 12:42PM UTC by anonymous comment:4

Could also be a separate function - triggerHandlers maybe. But that could be confused with triggerHandler. Anyway, the name would make the difference pretty clear IMHO.

Changed May 07, 2013 03:22PM UTC by timmywil comment:5

component: unfiledevent
priority: undecidedlow
status: newopen

I agree there is a small hole in the API here (we've had other complaints as well), but I'm not sure the solution. There should be a simpler way to trigger all handlers in a collection without triggering default actions. Creating an event object with the default already prevented is probably the best idea so far, but not quite the same thing (see http://bugs.jquery.com/ticket/10794). And I think we can do better than recommend re-wrapping each element with jQuery to call triggerHandler.

Changed May 07, 2013 05:41PM UTC by dmethvin comment:6

_comment0: The OP says there is "no way at all (besides calling $.event.trigger manually) to trigger bound events on a bunch of objects without executing the browser's default action." As Scott points out that's not true. It's pretty simple to create a "plugin" to do this using `.triggerHandler()`, and the extra overhead isn't much compared to the cost of firing events. \ {{{ \ $.fn.triggerHandlers = function( event, data ) { \ return this.each(function() { \ $( this ).triggerHandler( event, data ); \ }); \ } \ \ What exactly is the use case? Does that plugin help? Given that we have rarely had anyone express the need for it over the years, is there a compelling reason to put it in core? \ \ Note that the `.triggerHandler()` method returns the return value of the event handler so if you need that (or for example wanted to honor stopPropagation across the elements in the collection, which is non-standard behavior) you'd want a different implementation. These situations may be relatively specialized so I'm not sure it helps for us to assume our second try will cover all needs either. \ 1367948538030725

The OP says there is "no way at all (besides calling $.event.trigger manually) to trigger bound events on a bunch of objects without executing the browser's default action." As Scott points out that's not true. It's pretty simple to create a "plugin" to do this using .triggerHandler(), and the extra overhead isn't much compared to the cost of firing events.

$.fn.triggerHandlers = function( event, data ) {
   return this.each(function() {
      $( this ).triggerHandler( event, data );
   });
}

What exactly is the use case? Does that plugin help? Given that we have rarely had anyone express the need for it over the years, is there a compelling reason to put it in core?

Note that the .triggerHandler() method returns the return value of the event handler so if you need that (or for example wanted to honor stopPropagation across the elements in the collection, which is non-standard behavior) you'd want a different implementation. These situations may be relatively specialized so I'm not sure it helps for us to assume our second try will cover all needs either.

Changed June 29, 2013 07:32PM UTC by dmethvin comment:7

resolution: → plugin
status: openclosed

Since nobody else has expressed an interest in this, I'll close the ticket with the recommendation that it be implemented as a plugin. Adding a boolean argument to an API signature isn't generally a good idea anyway.