How to implement event-driven JavaScript without involving any DOM element?
Sure! The keyword you're looking for is "pubsub". Here are some well-known implementations:
- As a jQuery plugin
- PubSubJS
- EventEmitter2
- Backbone.Events
But you could also do it yourself, like so:
window.pubsub = (function () {
var eventToListeners = {};
return {
sub: function (event, callback) {
if (!eventToListeners.hasOwnProperty(event)) {
eventToListeners[event] = [];
}
eventToListeners[event].push(callback);
},
pub: function (event, args) {
if (eventToListeners.hasOwnProperty(event)) {
for (var i = 0; i < eventToListeners[event].length; ++i) {
try {
eventToListeners[event][i].call(null, args);
} catch (e) {
if (console && console.error) {
console.error(e);
}
}
}
}
}
};
}());
// Sample usage:
pubsub.sub("arraySorted", function () {
console.log("array was sorted");
});
var myArray = [2, 3, 1];
myArray.sort();
pubsub.pub("arraySorted");
In newish browsers, we've added the ability to construct an EventTarget directly:
const et = new EventTarget();
et.addEventListener("arraySorted", () => {
console.log("array was sorted");
});
const myArray = [2, 3, 1];
myArray.sort();
et.dispatchEvent(new Event("arraySorted"));
See https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/EventTarget for more examples as well as a browser compatibility table. As of the time of this writing it only works in Chrome (64+) and Firefox (59+), but over time support will expand to include Safari and Edge.
Mixing Backbone.Events into your object would give you this. (See Backbone.js)