I sometimes find myself wanting custom events on a global object with JQuery.
For example:
$(window).trigger('blah', {x: 'y'});
This plugin is designed to provide exactly that, except faster:
$.multicast('blah')({x: 'y'});
Full plugin code (minus test pages, really gotta get some qunit going on):
(function ($) {
"use strict";
var namedDelegates = {},
guid = 0,
multicastDelegate = function () {
var targets = {},
proxy = function () {
var args = arguments,
useargs = args.length > 0,
results = [],
site;
for (site in targets) {
if (targets.hasOwnProperty(site)) {
if (useargs) {
results.push(targets[site].apply(this, args));
} else {
results.push(targets[site].call(this));
}
}
}
if (proxy.aggregate) {
return proxy.aggregate.call(this, results);
}
return results;
};
$.extend(proxy, {
exists: function () {
var site;
for (site in targets) {
if (targets.hasOwnProperty(site)) {
return true;
}
}
return false;
},
add: function (func, key) {
if (typeof (func) === 'string') {
var temp = func;
func = key;
key = temp;
}
guid += 1;
if (!key) {
key = guid;
}
targets[key] = func;
},
remove: function (key) {
if (targets.hasOwnProperty(key)) {
delete targets[key];
}
},
callsites: function () {
return $.extend({}, targets);
},
aggregate: null
});
return proxy;
};
$.multicast = function (name) {
if (!namedDelegates[name]) {
namedDelegates[name] = multicastDelegate();
}
return namedDelegates[name];
};
$.extend($.multicast, {
aggregates: {
any_or_empty: function (args) {
var r = args.length === 0,
i,
l = args.length;
for (i = 0; i < l && !r; ++i) {
r = r || args[i];
}
return r;
},
all_or_empty: function (args) {
var r = args.length === 0,
i,
l = args.length;
for (i = 0; i < l && r; ++i) {
r = r && args[i];
}
return r;
},
atLeastN: function (n) {
return function (args) {
var r = 0,
i,
l = args.length;
if (l < n) { return false; }
for (i = 0; i < l && r < n; ++i) {
r += !!args[i] ? 1 : 0;
}
return r === n;
};
},
all: function (args) {
var r = args.length !== 0,
i,
l = args.length;
for (i = 0; i < l && r; ++i) {
r = r && args[i];
}
return r;
}
}
});
}(jQuery));
Eventually I'll get around to uploading this to github (I am waiting on the new plugin site). Feel free to use this.
License header is and has been since I started using this:
/**
* jQuery.multicast
* Copyright (c) 2008 Bill Barry - after.fallout(at)gmail(dot)com | http://16randombytes.blogspot.com
* Dual licensed under MIT and GPL.
* Date: 13 Dec 2009
*/
I'd prefer if you kept it if you use this code, perhaps with a link here (when I do get this on JQuery plugins, I'll link there from here and update the header).
How can I make this code better?