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. >
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
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);
};