Skip to content

Instantly share code, notes, and snippets.

@uolcano
Created August 16, 2016 10:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save uolcano/9722acb3b6b0ef480cd8fdd1d0afb867 to your computer and use it in GitHub Desktop.
Save uolcano/9722acb3b6b0ef480cd8fdd1d0afb867 to your computer and use it in GitHub Desktop.
An object(s) event wrapper method, compatible with IE8+
! function() {
if (typeof Array.prototype.forEach != 'function') {
Array.prototype.forEach = function(fn) {
var arr = Object(this),
i = 0,
len = 0;
if (Object.prototype.toString.call(arr).slice(8, -1) != 'Array') {
console.log('Error: Array.prototype.indexOf - the caller must be an array!');
return;
}
if (!(len = arr.length)) return;
do {
fn(arr[i], i, arr);
} while (++i < len);
fn = arr = null;
}
}
}();
! function() {
// source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice#Streamlining_cross-browser_behavior
// deal with that slice can not be call with DOM elements in IE < 9
'use strict';
var slice = Array.prototype.slice;
try {
// slice can not be used with DOM elements in IE < 9
slice.call(document.documentElement);
} catch (e) {
Array.prototype.slice = function(begin, end) {
end = typeof end != 'undefined' ? end : this.length;
// if the caller is an native Array
if (Object.prototype.toString.call(this).slice(8, -1) == 'Array') {
return slice.call(this, begin, end);
}
var i, size, start, last,
obj = Object(this),
copy = [],
len = obj.length;
// format arguments
start = typeof begin != 'number' ? 0 :
begin >= 0 ? begin :
Math.max(0, len + begin);
last = typeof end != 'number' ? len :
end >= 0 ? Math.min(end, len) :
len + end;
size = last - start;
if (size > 0) {
copy = new Array(size);
// process when slice bound to a string
if (obj.charAt) {
for (i = 0; i < size; i++) {
copy[i] = obj.charAt(start + i);
}
} else {
for (i = 0; i < size; i++) {
copy[i] = obj[start + i];
}
}
}
return copy;
};
}
}();
/*****************************
@namespace: window.uTools
*****************************/
// @description: Single object's events wrapper
// usage: var div = document.getElementsByTagName('div')[0],
// $div = $.wrp(div);
// function callback (event){
// // process
// }
// $div.on('click', callback);
// $div.off('click', callback);
// $div.trigger(event)
// $div.destroy('click');
! function(global) {
var $ = global.uTools = {};
function EventWrap(obj) {
if (typeof obj != 'object') return;
var __self = this;
this.source = obj;
this.handlers = {};
this.handle = function(event) {
__self.trigger(event);
}
};
EventWrap.prototype = {
constructor: EventWrap,
on: function(type, fn) {
if (this.handlers[type] == null) {
var elm = this.source;
this.handlers[type] = [];
if (elm.addEventListener) {
elm.addEventListener(type, this.handle, false);
} else if (elm.attachEvent) {
elm.attachEvent('on' + type, this.handle);
} else {
elm['on' + type] = this.handle;
}
}
this.handlers[type].push(fn);
},
off: function(type, fn) {
var handlers, len, idx;
if (this.handlers[type] != null) {
handlers = this.handlers[type];
len = handlers.length;
if (len) {
idx = handlers.indexOf(fn);
handlers.splice(idx, 1);
}
}
},
destroy: function(type) {
var elm = this.source;
if (elm.removeEventListener) {
elm.removeEventListener(type, this.handle, false);
} else if (elm.detachEvent) {
elm.detachEvent('on' + type, this.handle);
} else {
elm['on' + type] = this.handle;
}
this.handlers[type] = null;
},
trigger: function(event) {
var handlers = this.handlers[event.type],
idx = 0,
len;
if (handlers == null) return;
len = handlers.length;
if (!len) return;
event = event || window.event;
event.target || (event.target = event.srcElement);
if (typeof event.preventDefault != 'function') {
event.preventDefault = function() {
event.returnValue = false;
};
}
// get the compatible currentTarget
if (typeof event.currentTarget != 'object' ||
(event.currentTarget.nodeType != 1 &&
event.currentTarget.nodeType != 9) ||
typeof event.currentTarget.nodeName != 'string' ||
event.currentTarget.nodeValue !== null) {
event.currentTarget = event.target;
do {
if (event.currentTarget == this.source) break;
} while (event.currentTarget = event.currentTarget.parentNode);
}
// trigger all registered handlers
do {
handlers[idx](event);
} while (++idx < len);
}
};
$.wrp = function(obj) {
return new EventWrap(obj);
}
}(window);
// @description: Multiple objects' events wrapper
// usage: var divs = document.getElementsByTagName('div'),
// $divs = $.mwrp(divs);
// function callback(event) {
// // process
// }
// $divs.on('click', callback);
// $divs.off('click', callback);
// $divs.trigger(event)
// $divs.destroy('click');
! function($) {
function MultiEventWrap(objs) {
if (typeof objs != 'object') return;
if (typeof objs.length != 'number' || !objs.length) return;
var arr = Array.prototype.slice.call(objs),
source = [];
arr.forEach(function(e) {
var $e = $.wrp(e);
source.push($e);
});
this.source = source;
arr = source = null;
}
['on', 'off', 'destroy', 'trigger'].forEach(function(name) {
MultiEventWrap.prototype[name] = function(type, fn) {
var elms = this.source;
elms.forEach(function(e) {
e[name](type, fn);
});
}
});
$.mwrp = function(objs) {
return new MultiEventWrap(objs);
}
}(uTools);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment