Skip to content

Instantly share code, notes, and snippets.

@DaveStein
Created November 22, 2011 01:30
Show Gist options
  • Save DaveStein/1384615 to your computer and use it in GitHub Desktop.
Save DaveStein/1384615 to your computer and use it in GitHub Desktop.
Singleton wrapper around $.Callbacks to emulate Backbone events
Events = (function( $ ) {
// Store each registered $.Callbacks object by namespace
var cache = {},
slice = [].slice;
return {
// Bind callback to event
bind : function( ev, callback, options ) {
// Make $.Callbacks default to having stopOnFalse
options = options || 'stopOnFalse';
// If this callback list does not exist, create it
if ( !cache[ ev ] ) {
cache[ ev ] = {
cb : $.Callbacks( options ),
funcs : []
}
}
// Add callback to $.Callbacks
cache[ ev ].cb.add( callback );
cache[ ev ].funcs.push( callback );
}, // bind
updateOptions : function( ev, options ) {
var inc, len, func;
// Ignore update if it didn't exist
if ( !cache[ ev ] ) {
return;
}
// Remove all callbacks from $.Callbacks
cache[ev].cb.empty();
// Create a new $.Callbacks list with the new options
cache[ ev ].cb = $.Callbacks( options );
// Get size of callback functions already added
len = cache[ ev ].funcs.length;
// Loop through array of callback functions to insert into fresh $.Callbacks
for ( inc = 0; inc < len; ++inc ) {
func = cache[ ev ].funcs[ inc ];
cache[ ev ].cb.add( func );
} // for inc
}, // updateOptions
unbind : function( ev, callback ) {
// Ignore unbind if it didn't exist
if ( !cache[ ev ] ) {
return;
}
// Remove from list
cache[ ev ].cb.remove( callback );
// Remove from cache of funcs for option change
cache[ ev ].funcs = $.grep( cache[ ev ].funcs, function(value) {
return value !== callback;
});
}, // unbind
trigger : function( ev ) {
// Ignore trigger if it doesn't exist
if ( !cache[ ev ] ) {
return;
}
// Get dynamic number of arguments, knowing first argument is always event
var args = slice.call( arguments ),
pass = args.splice(1);
// Call $.Callbacks fire method with right arguments
cache[ ev ].cb.fireWith( null, pass );
} // trigger
} // return
})( jQuery ); // Events
var a = function() {
console.log('a');
return false;
};
var b= function() {
console.log('b');
};
Events.bind( 'foo', a );
Events.bind( 'foo', b );
// Logs a
Events.trigger( 'foo' );
Events.updateOptions( 'foo', '' );
// Logs a then b
Events.trigger( 'foo' );
Events.updateOptions( 'foo', 'stopOnFalse' );
// Logs a
Events.trigger( 'foo' );
Events.unbind( 'foo', a );
// Logs b
Events.trigger( 'foo' );
@DaveStein
Copy link
Author

Thanks @jaubourg for that catch on #30. I didn't need unbind where I first wrote this so didn't see that bug yet. Also you're right about fireWith since fire just calls fireWith anyway. Didn't look at the internals until just now.

@jaubourg
Copy link

Here is my take on it. I have removed the options in bind given how situational it is (will work the first time, not the second, etc).

https://gist.github.com/1387553

@DaveStein
Copy link
Author

DaveStein commented Nov 23, 2011 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment