//sparkl javascript library //February 2008 //original code Neil J Anderson //rubbish about: http://neilanderson.freehostia.com/ //version 0.1 /* DOCUMENTATION This is the sparkl core module, required by most of the other modules, anything that could reasonably be required by more than one module should be added here. Examples would be a mixin clas,. general class methods: extend, augment, clone. I've put the event attaching removing stuff directly onto the namespace as they're probably going to be used by most modules. nja - 2008-02-06 TO DO / REVISION HISTORY */ /* CORE MODULE CONTENTS * sparkl namespace * event handling */ //namespace var sparkl = {}; /* EVENT HANDLING PROPERTIIES * cache -- events cache for IE GENERAL METHODS * load -- attach function to window's load * unload -- attach function to window's unload * add -- attach an event to an element * remove -- detach an event FUNCTION METHODS called by attaned functions * stop -- stops event bubbling * prevent -- prevent default behaviour CLEANUP * cleanup a private method automatically called when a page unloads which detaches all added events. This prevents memory leaks in IE */ //EVENTS CODE //PROPERTIES //ie event cache sparkl.cache = []; //METHODS //add an event handler to the window when load fires sparkl.load = function(){ if (window.addEventListener){ //w3c DOM model return load = function(funct, capture){ window.addEventListener('load', funct, capture); }; } else if(window.attachEvent){ return load = function(funct){ window.attachEvent('onload', funct); }; }; }(); //unload event handler sparkl.unload = function(){ if (window.addEventListener){ //w3c DOM model return unload = function(funct, capture){ window.addEventListener('unload', funct, capture); }; } else if(window.attachEvent){ return unload = function(funct){ window.attachEvent('onunload', funct); }; }; }(); //add event sparkl.add=(function(){ var i = 0; if (window.addEventListener){ //w3c DOM model return add = function(el, typ, funct, capture){ el.addEventListener(typ, funct, capture); }; } else if (window.attachEvent){ //IE DOM model return add = function(el, typ, funct){ i++; var handle = 'fx' + typ + i;//unique id if(el.tagName){ el.setAttribute(handle,'on'); var fn = function(){ var trg = window.event.srcElement;//null for window var tag = handle; while (trg.getAttribute(tag)!='on'){ trg = trg.parentNode;//walk up dom }; funct.call(trg, window.event); }; sparkl.event.cache.push([el, typ, handle, funct, fn]); } else{ fn = funct; }; el.attachEvent('on' + typ, fn); }; }; })(); //remove an event sparkl.remove = function(){ if (window.removeEventListener){ return remove = function(el, typ, funct, capture){ el.removeEventListener(typ, funct, capture); }; } else if(window.detachEvent){ return remove = function(el, typ, funct){ var eventCache = sparkl.cache; for(var i= eventCache.length-1; i>=0; i--){ if(eventCache[i][0] == el && eventCache[i][1] == typ && el.getAttribute(eventCache[i][2]) && funct === eventCache[i][3]){ el.detachEvent('on'+typ, eventCache[i][4]); eventCache.splice(i,1); }; }; }; }; }(); //FUNCTION METHODS //called by functions //lazy load // you have to get the event -- f(e){sparkl.prevent(e);} //stop bubbling sparkl.stop = function(e){ if(e.stopPropagation){ e.stopPropagation();//first call stop stop = function(e){ e.stopPropagation(); }; } else{ e.cancelBubble = true; stop = function(e){ e.cancelBubble = true; }; }; }; //prevent default behavior sparkl.prevent = function(e){ if(e.preventDefault){ e.preventDefault();//first call prevent prevent = function(e){ e.preventDefault(); }; } else{ e.returnValue = false; prevent = function(e){ e.returnValue = false; }; }; }; //CLEANUP //unattach all events //used to prevent IE memory leaks sparkl.cleanup = function(){ var eventCache = sparkl.cache for(var i = eventCache.length - 1; i>=0; i--){ if(window.detachEvent){ eventCache[i][0].detachEvent('on'+eventCache[i][1],eventCache[i][4]); }; }; }; //call the cleanup function sparkl.unload(sparkl.cleanup);