Uploaded image for project: 'Moodle'
  1. Moodle
  2. MDL-68699

Consider migration away from native jQuery event triggers

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Open
    • Priority: Minor
    • Resolution: Unresolved
    • Affects Version/s: 3.9
    • Fix Version/s: None
    • Component/s: JavaScript
    • Labels:
      None
    • Affected Branches:
      MOODLE_39_STABLE

      Description

      I've been trying to solve an issue where I was previously listening for a native event and have had to update my code to listen for an Event generated by core/custom_interaction_events::trigger().

      I have hit a snag because the two APIs are not compatible and lead to different results.

      These are my findings so far:

      JavaScript Events

      jQuery:

      The following trigger:

      element.trigger('someEvent', 'Hello', 'Marvin');
      

      1. only triggers to jQuery listeners - i.e. those added via a call like:

        $.on('someEvent', handler});
        

      2. provides any provided parameters ( e.g. 'Hello', 'Marvin', etc) as arguments after the Event, i.e.

        $.on('someEvent', function(eventObject, saluation, name) {
        });
        

      Vanilla JS:

      The folloiwng trigger:

      element.dispatchEvent(new CustomEvent('someEVent', {
          bubbles: true,
          detail: [
              'Hello',
              'Marvin',
          ],
      });
      

      1. Trigger both Vanilla listeners, and jQuery listeners. i.e. both of the following will be triggered:

        $.on('someEvent', handler});
        document.addEventListener('someEvent', handler);
        

      2. Passes the additional parameters in the detail element into the detail element of the eventual handler. e.g.

        $.on('someEvent', function(e) {
            window.console.log(e.detail); // Will return `['Hello', 'Marvin']`
        }});
        document.addEventListener('someEvent', e => {
            window.console.log(e.detail); // Will return `['Hello', 'Marvin']`
        });
        

      Question

      How do we provide a migration path from jQuery events to vanilla events?

      With difficulty.

      Issues:

      1. They have a different API (detail vs. params)
      2. jQuery listens to vanilla events but does not trigger vanilla events

      Possible solutions:

      Multiple triggers

      When we call element.trigger() we also generate a new CustomEvent with a different name

      Example:

       
      // In core/custom_interaction_events::triggerEvent():
      $(e.target).trigger(eventName, [{originalEvent: e}]);
      e.target.dispatchEvent(new CustomEvent(getNativeEventName(eventName), {
          bubbles: true,
          detail: {
              originalEvent: e,
          },
      }));
       
      // Existing (b/c way):
      $(someDiv).on(CustomEvents.someEvent, function(e, data) {
          window.console.log(data.originalEvent);
      });
       
      // Listen to new event via jQuery:
      $(someDiv).on(CustomEvents.getNativeEventName(CustomEvents.someEvent), function(e) {
          window.console.log(e.detail.originalEvent);
      });
       
      // Listen to new event via native APIs:
      someDiv.addEventListener(CustomEvents.someEvent, function(e) {
          window.console.log(e.detail.originalEvent);
      });
      
      

      This works for the most part but is cumbersome:

      1. We need to generate an Event name for both
      2. For Vanilla listeners we need to listen for a different event name to allow for b/c
      3. Possible issues with stopImmediatePropagation on whichever event type is called first

        Attachments

          Activity

            People

            Assignee:
            Unassigned Unassigned
            Reporter:
            dobedobedoh Andrew Lyons
            Participants:
            Component watchers:
            Andrew Lyons, Dongsheng Cai, Huong Nguyen, Jun Pataleta, Michael Hawkins, Shamim Rezaie, Simey Lameze
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Dates

              Created:
              Updated: