Skip to content

Instantly share code, notes, and snippets.

@jaeschrich
Last active December 11, 2015 10:28
Show Gist options
  • Save jaeschrich/4586997 to your computer and use it in GitHub Desktop.
Save jaeschrich/4586997 to your computer and use it in GitHub Desktop.
on off style event emitters with fall backs for older browsers
/**
* wrap
* Usage
* var a = document.querySelector('#test');
* wrap(a)
*
* or
*
* var a = wrap(document.querySelector('#test'));
*
* a.on('event', callback);
* a.off('event', callback);
*/
(function (global) {
var extend = function (a, b) { for (var i in b) { a[i] = b[i]; } return a; };
/**
* @class Wrapped
* The base class, which adds on and off methods
*/
function Wrapped(el) {
this._el = el;
if (!el.addEventListener) {
this.legacy = true;
this._events = {};
}
else this.legacy = false;
}
/**
* @method on
* adds an event to the event queue
* @param {string} name The name of the event you are adding to
* @param {function} cb The callback function
*/
Wrapped.prototype.on = function (name, cb) {
if (!this.legacy) this.addEventListener.apply(this, arguments);
else {
var fullName = "on" + name.replace(" ", ""); // ignore spaces
if (!this[fullName]) {
this._events[name] = [];
this[fullName] = function () {
for (var cb in this._events[name]) {
this._events[name][cb].apply(this, arguments);
}
};
}
this._events[name].push(cb);
}
return this;
};
/**
* @method off
* removes a callback from the queue
* needs a method name
* @param {string} name The event to remove the callback from
* @param {function} cb The callback to remove. The method name, not in quotes. Only for named functions
* @returns {function} the deleted callback
*/
Wrapped.prototype.off = function (name, cb) {
if (!this.legacy) this.removeEventListener.apply(this, arguments);
else {
var index = this._events[name].indexOf(cb);
return this._events[name].pop(index);
}
return this;
};
/**
* returns an element that has been extended with the Wrapped class
* @param {Element} e A DOM element to be wrapped
* @returns {Element} e that has been extended
*/
global.wrap = function wrap(e) {
return extend(e, new Wrapped(e));
};
})(window);
/*
test code:
var a = document.getElementById("test");
wrap(a);
function clicked(){
alert("works");
a.off('click', clicked);
}
a.on('click', clicked);
var b = wrap({}); // dummy object
b.on('event', function (data) {
alert('works 1');
}).on('event', function () {
alert("works 2")
b.off('event', arguments.callee);
});
b.onevent('hi');
b.onevent('hi');
*/
/*
should get following alerts:
works (on clicking button first time)
(nothing) (on clicking button second time)
works 1
works 2
works 1
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment