JQuery ".triggerHandler () versus .trigger ()" when multiple items are selected

The jQuery ".triggerHandler ()" mechanism, unlike the ".trigger ()", only works with the first element referenced by the jQuery object for which it called. In other words,

$('.all-over-the-page').triggerHandler("readjust"); 

it will only call the readjust handler for the first element with the all-over-the-page class, even if there are many elements on the page with this class. On the other hand, the ".trigger ()" method will affect all of them.

I understand that I can use ".each ()" to get around this (or just write my own replacement that does this for me), but is there any justification for why the two are different in this regard? That doesn't make sense to me. (I understand, of course, that this almost certainly cannot be changed now.)

edit to clarify:

It is probably easier to understand why I am cracking my head over this if I provide the code-style context that I have. When I compiled code for various "widgets" on a page, this often included event handlers. A good example is a form that has received some fields whose relevance is controlled by a checkbox or radio button or selector. A common example of this is the โ€œDelivery Addressโ€ box, which appears on zillion e-commerce sites: if checked, the delivery address is disabled and the billing address is used.

Now consider that some other code, for its own reasons, completely independent of the checkbox-control widget, really does things in a form that can include updating the checkbox settings programmatically. In this case, another widget code may use "triggerHandler ()" to report any widgets, "hey, I updated some things so you can re-check the current status and adjust if necessary."

Thus, if ".triggerHandler ()" works with all the selected elements, I could use:

  $theForm.find('input, select, textarea').triggerHandler('change'); 

and all these handlers can work and do whatever they need. As I said, it's easy enough to write:

  $theForm.find('input, select, textarea').each(function() { $(this).triggerHandler('change'); }); 
+7
source share
1 answer

"... is there any justification for why they are different in this regard?"

I think the idea is that triggerHandler() intended to call a function that you, as a handler, as if it were any other function.

Thus, they made triggerHandler() so that the function is called only once, it returns the actual return value of the function and does not affect the DOM with bubbling or default behavior.

Of course, the function may fail if they change the this value to something other than the DOM element, so they just use the first matched element.

If you just want to use your function, I would probably just keep a reference to it and call it directly or as an .each() argument.

 $('.element').each( handler_func ); 

... until you need an event object.


EDIT: Or, if you want to return values โ€‹โ€‹from a call, use .map() instead:

 var return_values = $('.element').map( handler_func ); 

EDIT:. Regarding the example provided in the updated question, a good solution might be to use the optional parameters option for trigger() [docs] so that you can pass preventDefault() and stopPropagation() to the handler.

 $('.elememts').bind( 'click', function( e, was_code_triggered ) { if( was_code_triggered ) { e.preventDefault(); e.stopPropagation(); } // your code }); // ... $('.elememts').trigger( 'click', true ); // pass "true" to let handler know // it wasn't a DOM event 

From .trigger() docs:

"Note the difference between the additional parameters that we pass here and the eventData parameter for the .bind() method. Both are mechanisms for passing information to the event handler, but the extraParameters argument for .trigger() allows the information to be determined when the event is .trigger() , while time as an argument to eventData for .bind() requires that the information is already computed during the binding of the handler. "

+11
source

All Articles