Skip to content

Instantly share code, notes, and snippets.

@chaozh
Created June 10, 2014 06:24
Show Gist options
  • Save chaozh/32988b154ac1b30ba238 to your computer and use it in GitHub Desktop.
Save chaozh/32988b154ac1b30ba238 to your computer and use it in GitHub Desktop.
a simple base js toolkit handle event
// Avoid `console` errors in browsers that lack a console.
(function() {
var method;
var noop = function () {};
var methods = [
'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error',
'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log',
'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd',
'timeStamp', 'trace', 'warn'
];
var length = methods.length;
var console = (window.console = window.console || {});
while (length--) {
method = methods[length];
// Only stub undefined methods.
if (!console[method]) {
console[method] = noop;
}
}
}());
//base class here
(function(exports, undefined){
"use strict";
//redefine document
var document = exports.document;
//name sapce
var BASE = function(n){
return document.getElementById(n);
};
//may confilct
exports.$ === undefined && (exports.$ = BASE);
/**
* event realted -- bind,remove,trigger
*/
BASE.e = {
// Private utility to generate unique handler ids
_counter :0,
_uid:function() { return "h" + BASE.e._counter++; },
add:function(element, eventType, handler){
if (document.addEventListener){
element.addEventListener(eventType, handler, false);
//deal with IE
}else if (document.attachEvent) {
if (BASE.e._find(element, eventType, handler) != -1) return;
// To invoke the handler function as a method of the
// element, we've got to define this nested function and register
// it instead of the handler function itself.
var wrappedHandler = function(e) {
if (!e) e = window.event;
// Create a synthetic event object with partial compatibility
// with DOM events.
var event = {
_event: e, // In case we really want the IE event object
type: e.type, // Event type
target: e.srcElement, // Where the event happened
currentTarget: element, // Where we're handling it
relatedTarget: e.fromElement?e.fromElement:e.toElement,
eventPhase: (e.srcElement==element)?2:3,
// Mouse coordinates
clientX: e.clientX, clientY: e.clientY,
screenX: e.screenX, screenY: e.screenY,
// Key state
altKey: e.altKey, ctrlKey: e.ctrlKey,
shiftKey: e.shiftKey, charCode: e.keyCode,
// Event-management functions
stopPropagation: function( ) {this._event.cancelBubble = true;},
preventDefault: function( ) {this._event.returnValue = false;}
};
// Invoke the handler function as a method of the element, passing
// the synthetic event object as its single argument.
// Use Function.call( ) if defined; otherwise do a hack
if (Function.prototype.call)
handler.call(element, event);
else {
// If we don't have Function.call, fake it like this.
element._currentHandler = handler;
element._currentHandler(event);
element._currentHandler = null;
}
};
// Now register that nested function as our event handler.
element.attachEvent("on" + eventType, wrappedHandler);
// Now we must do some record keeping to associate the user-supplied
// handler function and the nested function that invokes it.
// We have to do this so that we can deregister the handler with the
// remove( ) method and also deregister it automatically on page unload.
// Store all info about this handler into an object.
var h = {
element: element,
eventType: eventType,
handler: handler,
wrappedHandler: wrappedHandler
};
// Figure out what document this handler is part of.
// If the element has no "document" property, it is not
// a window or a document element, so it must be the document
// object itself.
var d = element.document || element;
// Now get the window associated with that document.
var w = d.parentWindow;
// We have to associate this handler with the window,
// so we can remove it when the window is unloaded.
var id = BASE.e._uid( ); // Generate a unique property name
if (!w._allHandlers) w._allHandlers = {}; // Create object if needed
w._allHandlers[id] = h; // Store the handler info in this object
// And associate the id of the handler info with this element as well.
if (!element._handlers) element._handlers = [];
element._handlers.push(id);
// If there is not an onunload handler associated with the window,
// register one now.
if (!w._onunloadHandlerRegistered) {
w._onunloadHandlerRegistered = true;
w.attachEvent("onunload", BASE.e._removeAllHandlers);
}
}
},
remove:function(element, eventType, handler) {
if (document.addEventListener){
element.removeEventListener(eventType, handler, false);
}else if (document.attachEvent){
// Find this handler in the element._handlers[] array.
var i = BASE.e._find(element, eventType, handler);
if (i == -1) return; // If the handler was not registered, do nothing
// Get the window of this element.
var d = element.document || element;
var w = d.parentWindow;
// Look up the unique id of this handler.
var handlerId = element._handlers[i];
// And use that to look up the handler info.
var h = w._allHandlers[handlerId];
// Using that info, we can detach the handler from the element.
element.detachEvent("on" + eventType, h.wrappedHandler);
// Remove one element from the element._handlers array.
element._handlers.splice(i, 1);
// And delete the handler info from the per-window _allHandlers object.
delete w._allHandlers[handlerId];
}
},
// A utility function to find a handler in the element._handlers array
// Returns an array index or -1 if no matching handler is found
_find : function(element, eventType, handler) {
var handlers = element._handlers;
if (!handlers) return -1; // if no handlers registered, nothing found
// Get the window of this element
var d = element.document || element;
var w = d.parentWindow;
// Loop through the handlers associated with this element, looking
// for one with the right type and function.
// We loop backward because the most recently registered handler
// is most likely to be the first removed one.
for(var i = handlers.length-1; i >= 0; i--) {
var handlerId = handlers[i]; // get handler id
var h = w._allHandlers[handlerId]; // get handler info
// If handler info matches type and handler function, we found it.
if (h.eventType == eventType && h.handler == handler)
return i;
}
return -1; // No match found
},
_removeAllHandlers :function() {
// This function is registered as the onunload handler with
// attachEvent. This means that the this keyword refers to the
// window in which the event occurred.
var w = this;
// Iterate through all registered handlers
for(var id in w._allHandlers) {
// Get handler info for this handler id
var h = w._allHandlers[id];
// Use the info to detach the handler
h.element.detachEvent("on" + h.eventType, h.wrappedHandler);
// Delete the handler info from the window
delete w._allHandlers[id];
}
}
};
/**
* DOM related
*/
BASE.dom = {
_ready: false,
_timer: null,
_e: [],
onload:function(handler){
if(BASE.dom._ready && typeof handler == "function")
handler();
if(BASE.dom._timer){
BASE.dom._e.push(handler);
}else{
BASE.e.add(exports, "load", BASE.dom._checkDomReady);
BASE.dom._e = [handler];
BASE.dom._timer = setInterval(BASE.dom._checkDomReady, 100);
}
/*
var temp = window.onload;
window.onload = function(){
if(typeof temp == "function")
temp();
if(typeof handler == "function")
handler(); //BUG
} */
},
_checkDomReady:function(event){
//console.log(event.currentTarget);
var i, len;
if(BASE.dom._ready) return true;
if(document && document.getElementById && document.body){
BASE.dom._ready = true;
//clear timer
clearInterval(BASE.dom._timer);
BASE.dom._timer = null;
for(i=0, len = BASE.dom._e.length;i<len;i++)
BASE.dom._e[i]();
}
return BASE.dom._ready;
}
};
/**
* Style related
*/
BASE.css = {
};
/**
* attribute related
*/
BASE.attr = {
addClass : function(element, className) {
var classArray = className.split(/\s+/),
result = element.className,
i =0,
classMatch = " "+result+" ",
len = classArray.length;
for(;i<len;i++){
if(classMatch.indexOf(" " + classArray[i] + " ") < 0){
result += (result ? " ":"") + classArray[i];
}
}
element.className = result;
},
removeClass: function(element, className) {
var targetClassArray = className.split(/\s+/),
oldClassArray = element.className.split(/\s+/),
tlen = targetClassArray.length,
olen = oldClassArray.length,
i, j;
for(i=0;i<olen;i++){
for(j=0;j<tlen;j++){
if(oldClassArray[i] == targetClassArray[j]){
oldClassArray.splice(i, 1);
break;
}
}
}
element.className = oldClassArray.join(" ");
},
hasClass: function(element, className){
var classMatch = " " + className + " ",
rclass = /[\t\r\n\f]/g;
if ( element.nodeType === 1 && (" " + element.className + " ").replace(rclass, " ").indexOf( classMatch ) >= 0 ) {
return true;
}
return false;
}
};
/**
* Test
*/
BASE.DEBUG = false;
BASE.log = function(){
var args = [];
function makeArray(arrayLikeThing) {
return Array.prototype.slice.call(arrayLikeThing);
}
if(BASE.DEBUG){
makeArray(arguments).forEach(function(arg) {
return args.push(arg);
});
return console.log.apply(console, args);
}
};
/**
* storage info
*/
BASE.bom = (function(){
if(typeof exports.localStorage == 'undefined'){
return {
//window name storage
setTemp:function(n,v){
var name = exports.name||"";
if(name.match(new RegExp( ";"+n+"=([^;]*)(;|$)"))){//先验证是否存在
exports.name = name.replace(new RegExp( ";"+n+"=([^;]*)"),";"+n+"="+v);
}else{
exports.name = name+";"+n+"="+v;
}
},
getTemp:function(n){
var name = exports.name||"";
var v = name.match(new RegExp( ";"+n+"=([^;]*)(;|$)"));
return v?v[1]:"";
},
clearTemp:function(n){
var name = exports.name||"";
exports.name = name.replace(new RegExp( ";"+n+"=([^;]*)"),"");
}
};
}else{
//local storage
var _storage = exports.localStorage;
return {
setTemp: function(key, value){
return _storage.setItem(key, value);
},
getTemp: function(key){
return _storage.getItem(key);
},
clearTemp: function(key){
return _storage.removeItem(key);
},
clearAll: function(){
return _storage.clear();
}
};
}
})();
})(window);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment