Last active
December 11, 2015 10:28
-
-
Save jaeschrich/4586997 to your computer and use it in GitHub Desktop.
on off style event emitters with fall backs for older browsers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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