Posted about 1 month ago. Visible to the public. Linked content. Auto-destruct in 3 days

Updated: Events triggered by jQuery cannot be observed by native event listeners

Added two utility functions to convert an app from triggering jQuery events to emitting native events instead.

This is relevant when you want to write new code without jQuery, but still have legacy code or jQuery plugins that trigger pure jQuery events. If your entire app is written in jQuery and you don't plan to use native libraries (like modern Unpoly versions), this does not affect you.


Fixing your own code

If possible, change your code so it doesn't use jQuery's trigger() function. Instead trigger native events using Element#dispatchEvent() or Unpoly's up.emit().

To simplify this refactoring is a jQuery function triggerNative() that you can use as a drop-in replacement for trigger():

Copy
jQuery.fn.triggerNative = function(...args) { this.each(function() { up.emit(this, ...args) }) return this }

With this you can replace a call like $element.trigger('change') with $element.triggerNative('change'). You may also pass event properties as a second argument.

Fixing library code

jQuery plugins like select2 or bootstrap-datepicker use trigger('change') to emit change events. These events are not observable by native listeners.

This case is a little harder to fix since we do not want to change library code.

The function can be applied to a jQuery element known to emit pure jQuery events. If it observes a pure jQuery event without an underlying native event, the jQuery event is stopped from propagation and bubbling. A native event is then emitted on the same element:

Copy
jQuery.fn.enableNativeEvent = function(eventName, convertedPropNames = []) { this.on(eventName, function($event) { // Only convert when there is not already a native event if (!$event.originalEvent) { let eventProps = up.util.only($event, ...convertedPropNames) up.emit($event.target, eventName, eventProps) up.event.halt($event) } }) return this }

Here is an example usage:

Copy
$element.select2().enableNativeEvent('change')

Make sure this function is applied before any other event listeners are registered to the given jQuery element, or events might be received twice.

The native event is emitted without additional properties outlining event details. If you need properties to be copied from the jQuery event to the native event, pass an array of property names as a second argument:

Copy
$element.enableNativeEvent('mousemove', ['clientX', 'clientY'])

Once an application no longer requires constant development, it needs periodic maintenance for stable and secure operation. makandra offers monthly maintenance contracts that let you focus on your business while we make sure the lights stay on.

Owner of this card:

Avatar
Henning Koch
Last edit:
about 1 month ago
by Henning Koch
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Henning Koch to makandra dev
This website uses cookies to improve usability and analyze traffic.
Accept or learn more