trigger vs triggerHandler in jQuery
It's never nice to see bugs crop up because libraries and browsers aren't interacting as expected. In this case jQuery can cause a bit of funk with newer versions of Chrome.
Here's a Chrome bug that flags some code on change.org that's stopped working in newer versions of Chrome. The TL;DR is that using jQuery's trigger
instead of triggerHandler
can cause problems when a browser provides a function with the same name as the event.
The jQuery docs explain it (emphasis added by yours truly):
Note: For both plain objects and DOM objects other than window, if a triggered event name matches the name of a property on the object, jQuery will attempt to invoke the property as a method if no event handler calls
event.preventDefault()
. If this behavior is not desired, use.triggerHandler()
instead.
I think it's pretty easy to get this wrong, because the jQuery API isn't clear on the distinction between trigger
and triggerHandler
through its function naming, and because - at least in my view - it does something unexpected in trigger
by calling functions on objects. It overreaches from jQuery events and into actual host-provided functions. I'm told it's down to perennial favourites submit
and click
, which have jQuery events and equivalent browser functions of the same name.
If you're curious, this is the offending code:
// This will break in newer versions of Chrome.
$(element).trigger('animate');
jQuery fires its own event handlers for animate
but then it also calls the browser's animate
function on HTMLElement
as well.
Before Web Animations started shipping, trying to call an animate
function on elements would've been just fine here (because no animate
function actually existed), but now we have one there's a problem. The animate
function from Web Animations expects a parameter containing properties to animate, a parameter which jQuery doesn't provide. Oops.
Incidentally, the same would happen if you called:
$(element).trigger('appendChild');
You actually want triggerHandler
, which is just like trigger
but without the "call the browser's function" bit.
Conclusion #
It may seem obvious once you understand jQuery's distinction, but the combination of jQuery's function naming and assumption that properties are functions to call is problematic.
At least there's an safety catch via triggerHandler
; just be sure to use it!