A lightweight event emitter and mixin with advanced features that don't get in the way.
var myObject = {'foo':'bar'};
var trigger = paperboy.mixin( myObject );
myObject.on('myevent', function( howMany ) {
console.log( howMany ); // 5
console.log( this ); // myObject
});
trigger('myevent', 5);
var trigger = paperboy.mixin( target )
- Adds on, off, one, is, and not to target. Returns the trigger function.paperboy.emitter()
- Returns a new object with on, off, one, is, not, and trigger functions.
NOTE: paperboy.mixin
returns the trigger function. It does not add it to the target.
Emitters trigger event listeners. The mixin
function turns any object into an emitter.
emitter.on( eventName, callback )
- adds a listener to theeventName
event.eventName
must be a string.emitter.one( eventName, callback )
- adds a listener that will remove itself after being triggered once.emitter.is( stateName, callback )
- adds a state listener that will be called when the emitter is instateName
.emitter.is.one( stateName, callback )
- adds a state listener that will remove itself after being triggered once.emitter.not( stateName, callback )
- adds a state listener that will be called when the emitter is not instateName
.emitter.not.one( stateName, callback )
- adds a state listener that will remove itself after being triggered once.
emitter.off( eventName, callback )
- removes a listener from an event.emitter.is.remove( eventName, callback )
- removes a listener from a stateful event.emitter.not.remove( eventName, callback )
- removes a listener from a stateful event.
emitter.trigger( eventName /*, add'l, args */ )
- triggers all event handlers foreventName
.emitter.trigger.is( stateName /*, add'l, args */ )
- puts the emitter in thestateName
state and triggers stateful listeners.emitter.trigger.not( stateName /*, add'l, args */ )
- takes the emitter out ofstateName
state and triggers stateful listeners.
NOTE: trigger
is not added by the mixin function. If you want trigger to be public you must attach it to the target yourself.
emitter.trigger.repeat( otherEmitter /*, [eventNames], [stateNames] */ )
- Causes this emitter to repeat events triggered on another emitter.
Stateful event listeners operate like $(document).ready()
and deferreds; when a listener is added to a stateful event it is triggered immediately if your emitter is in that state.
Listeners added with emitter.in
apply when the emitter is in a state, listeners on emitter.not
apply when the emitter is not in a state. States are set with trigger.is
and trigger.not
. Listeners added to emitter.not
will fire immediately if no states have been declared.
emitter.is('live', callback1); // does not fire immediately.
emitter.trigger.is('live'); // puts the emitter in 'live' state and fires the listener above.
emitter.is('live', callback2); // fires immedately
emitter.trigger.not('live'); // takes the emitter out of the live state.
emitter.trigger.is('live'); // fires both listeners
Stateful listeners are removed with the is.remove
and not.remove
functions.
emitter.is.remove('live', callback1); // removes callback1
Run-once functionality, like emitter.one
is provided with is.one
and not.one
emitter.is.one('live', callback3); // callback3 will be called exactly once.
Until an emitter is put in a state with trigger.is
, listeners applied to not
will be exectued immediately.
To catch errors early, before they hit production, you can whitelist event names. If anyone tries to add to or trigger events that are not white listed an error will be thrown.
// with a mixin
var target = {};
var trigger = paperboy.mixin( target, ['eventOne', 'eventTwo']);
// with an emitter
var emitter = paperboy.emitter(['eventOne', 'eventTwo']);
emitter.on('eventOne', function(){}); // works
emitter.on('eventOen', function(){}); // throws an error
You can have a paperboy emitter repeat the events triggered by other emitters. This is done with the repeat
property of the trigger
function.
// This will cause `emitter` to echo every event that `otherPaperboyEmitter` triggers.
emitter.trigger.repeat( otherPaperboyEmitter );
// This will cause `emitter` to echo specific events that `otherEmitter` throws.
// You can even repeat events from jQuery objects or anything else with an `on` function.
emitter.trigger.repeat( otherEmitter, ['pickup', 'putdown'] );
emitter.trigger.repeat( $('.button'), ['click'] );
emitter.trigger.repeat( backboneModel, ['update'] );
If you want to repeat stateful events send in a third argument.
emitter.trigger.repeat( otherPaperboyEmitter, [eventNames], [stateNames]);
Listeners applied to the *
event will be triggered for each event. The first argument will be the event name.
on
/off
/one
/trigger
. Just like jQuery and Backbone.- Learn the advanced features as you need them, they're never in the way.
- Helpful error messages tell you which events are whitelisted or which callback caused an error.
- Event listeners are always kept private.
- Passing in a whitelist of event names will prevent typos.
- The
trigger
function is private by default. If you want it to be public simply add it to the target. - All callback errors are caught and logged. No subscriber can take down your event.
- Listener arrays are copied before being iterated over; removing a listener in a callback will not cause a bug. This is overlooked in many pubsubs.
- Chain several emitters together in one module to easily unify a whole package.
- Use the * event and a map of events->objects to make your code clear and concise.
- Stateful events keep track of the state of your app.
- Verified to work in IE6, Chrome 4, Firefox 3, and Safari 5.0.5 and above.
- Works with or without RequireJS, Node, or other module systems.
Also it's small. Just 1k minified and gzipped.
Inspired by LucidJS