jQuery .trigger() multiple events

Viewed 30937

I'm writing a jQuery plugin and using .on and .trigger as my pub/sub system. However, I want to trigger multiple events in different scenarios.

Is this possible to do as one string, like the .on method?

Goal:

$this.trigger("success next etc");    // doesn't work

Current solution:

$this
    .trigger("success")
    .trigger("next")
    .trigger("etc");                  // works, triggers all three events

Any suggestions?

4 Answers

You could extend the original .trigger() Method prototype:

(function($) {
  const _trigger = $.fn.trigger;
  $.fn.trigger = function(evtNames, data) {
    evtNames = evtNames.trim();
    if (/ /.test(evtNames)) {
      evtNames.split(/ +/).forEach(n => _trigger.call(this, n, data));
      return this;
    }
    return _trigger.apply(this, arguments);
  };
}(jQuery));


$("body").on({
  foo(e, data) { console.log(e, data); },
  bar(e, data) { console.log(e, data); },
  baz(e, data) { console.log(e, data); },
});


$("body").off("bar"); // Test: stop listening to "bar" EventName
$("body").trigger(" foo    bar baz ", [{data: "lorem"}]); // foo, baz
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

Code explained


// Keep a reference to the original prototype
const _trigger = $.fn.trigger;

$.fn.trigger = function(evtNames, data) {

  // Remove leading and ending whitespaces 
  evtNames = evtNames.trim();

  // If the string has at least one whitespace
  if (/ /.test(evtNames)) {

    // Split names into Array (Treats multiple spaces as one)
    evtNames.split(/ +/)
    // Call the original .trigger() method for one eventName (and pass data)
      .forEach(n => _trigger.call(this, n, data));

    // End here.
    // Return this (Element) to maintain jQuery methods chainability for this override.
    return this;
  }

  // No whitespaces detected
  // Pass all arguments to the original .trigger() Method immediately.
  // The original method already returns this (Element), so we also need to 
  // return it here to maintain methods chainability when using this override. 
  return _trigger.apply(this, arguments);
};
Related