This is a Javascipt library which helps us writing event driven Javascript code.
- No dependencies, no jQuery, no other library.
- It is not about the DOM. jem.js is for your custom events.
- Any kind of contribution is welcome.
Using events instead of calling methods reduces coupling.
Assume that you have two modules in your web page which communicates by calling methods of each other. When you want to remove one module from the page, you have to change the code of the other module and test whole page.
With events, however, to remove a module from the page, all you need is to remove the module.
As you can see below, when you want to remove moduleA, you need to update moduleB, too.
var moduleA = (function () {
var foo = "foo";
var bar = "bar";
// some code related to moduleA
// ...
function updateGUI() {
alert("foo: " + foo + ", bar: " + bar);
}
return {
onBarUpdated: function (newValue) {
bar = newValue;
updateGUI();
},
onFooUpdated: function (newValue) {
foo = newValue;
updateGUI();
}
};
}());
var moduleB = (function () {
var foo = "";
var bar = "";
// some code related to moduleB
// ...
return {
updateFoo: function (newValue) {
foo = newValue;
// ...
// do something and notify moduleA
moduleA.onFooUpdated(foo);
},
updateBar: function (newValue) {
bar = newValue;
// ...
// do something and notify moduleA
moduleA.onBarUpdated(bar);
}
};
}());
Here in this code, you are free to remove any of the modules. There is no moduleA in moduleB and there is no moduleB in moduleA.
var moduleA = (function () {
var foo = "foo";
var bar = "bar";
// some code related to moduleA
// ...
function updateGUI() {
alert("foo: " + foo + ", bar: " + bar);
}
jem.on('FooUpdated', function (eventName, attributes) {
foo = attributes.foo;
updateGUI();
});
jem.on('BarUpdated', function (eventName, attributes) {
bar = attributes.bar;
updateGUI();
});
return {
// other module methods.
};
}());
var moduleB = (function () {
var foo = "";
var bar = "";
// some code related to moduleB
// ...
return {
updateFoo: function (newValue) {
foo = newValue;
// ...
// do something and fire an event
jem.fire('FooUpdated', { foo : foo });
},
updateBar: function (newValue) {
bar = newValue;
// ...
// do something and fire an event
jem.fire('BarUpdated', { bar : bar });
}
};
}());
jem.fire('MessageSentEvent');
jem.fire('RegistrationCompletedEvent');
jem.fire('MusicStartedEvent');
Fire an event with specific attributes. Event handlers can use this attributes or you can use those attributes to filter events for a specific handler.
jem.fire('MessageSentEvent', { message : 'Hello, World', messageId : 1312});
jem.fire('RegistrationCompletedEvent', { username : 'sedran', name : 'Serdar', surname : 'Kuzucu' });
jem.fire('MusicStartedEvent', { author : 'Metallica', title : 'Am I Evil?' });
// Fire event after 15 minutes
jem.fire('TimeIsOverEvent', {}, 15 * 60 * 1000);
jem.fire('MessageSentEvent', { message : 'Hello, World', messageId : 1312}, 100);
jem.fire('RegistrationCompletedEvent', { username : 'sedran', name : 'Serdar', surname : 'Kuzucu' }, 3000);
// Fire event after the current execution finishes
jem.fire('MusicStartedEvent', { author : 'Metallica', title : 'Am I Evil?' }, 0);
// Fire event after 15 minutes
// Then fire it again every minute
jem.fire('AddToCartEvent', {}, 15 * 60 * 1000, 60 * 1000);
// Fire event after the current execution finishes
jem.fire('SendAlertEvent', { title : 'Are you still here?' }, 10000, 10000);
// Imagine when a new user is registered,
// you fire UserRegisteredEvent event somewhere in the code
jem.on('UserRegisteredEvent', function (eventName, eventAttributes) {
// Handle the event
$(".username").html(eventAttributes.username);
});
jem.on('BlogPostedEvent', { category : 'Education' }, function (eventName, eventAttributes) {
// A blog entry posted by user into the Education category
});
jem.once('BlogPostedEvent', function (eventName, eventAttributes) {
// A blog entry was posted
// This code will be called only the first time the event occured.
});
Attach a one-time event handler for a specific event which has specific attributes specified as filters.
jem.once('BlogPostedEvent', { category : 'Education' }, function (eventName, eventAttributes) {
// A blog entry posted by user into the Education category
// This code will be called only the first time the event occured.
});
// Handle both UserLoginEvent and UserSignupEvent with a single callback
jem.on(['UserLoginEvent', 'UserSignupEvent'], function (eventName, eventAttributes) {
// Handle the event
$(".username").html(eventAttributes.username);
});
// Handle the one that occurs first
jem.once(['UserLoginEvent', 'UserSignupEvent'], function (eventName, eventAttributes) {
// Handle the event
$(".username").html(eventAttributes.username);
});
You can use '*' as an event name to handle all events with a single handler function.
jem.on('*', function (eventName, eventAttributes) {
// All fired events will come here.
});
jem.on('*', {id : 5}, function (eventName, eventAttributes) {
// All fired events with attribute `id = 5` will come here.
});
// Let's use jem.once
jem.once('*', function (eventName, eventAttributes) {
// The first fired event will come here
// And no other event will be handled by this handler
});
jem.once('*', {id : 5}, function (eventName, eventAttributes) {
// The first fired event with attribute `id = 5` will come here.
// And no other event will be handled by this handler
});
jem.off('BlogPostedEvent');
// Event Handler:
var mHandler = function (eventName, eventAttributes) {
// does some nasty things here
};
// Register event handler:
jem.on('HelloEvent', mHandler);
// Unregister event handler
jem.off('HelloEvent', mHandler);
Listening multiple events with single handlerDecision: implement one ofjem.on('A,B', handler)
orjem.on(['A', 'B'], handler)
Add unit testsAdd demo usages- Add cancellation method for scheduled event firing