Skip to content

Instantly share code, notes, and snippets.

@avit
Created October 16, 2010 20:05
Show Gist options
  • Save avit/630216 to your computer and use it in GitHub Desktop.
Save avit/630216 to your computer and use it in GitHub Desktop.
// Gets called whenever an en event is fired
Handle = function(ev){
// Step 1: Event setup
var elements = [],
target = ev.target,
isPropagationStopped = false,
isDefaultPrevented = false;
// We are on the Capture Phase to start with
ev.eventPhase = 0;
ev.stopPropagation = function(){
isPropagationStopped = true;
}
ev.preventDefault = function(){
isDefaultPrevented = true;
}
// Step 2: Calculate parent node path
// Loop up through the DOM and collect all of the
// parent nodes into the 'elements' array
var elements = [];
do{
elements.push(target);
}while((target = target.parentNode));
// Reverse the list so it's a bit easier to read
// in the following for loop
elements.reverse();
// Step 3: Execute Capture Phase handlers
// For all of the elements in the list...
for(var i = 0 ; i < elements.length; i++){
// If stopPropagation() was called, end the loop -
// we're done.
if(isPropagationStopped){
break;
}
var currentElement = elements[i],
// If there are any event handlers set for
// this element, event type and phase,
// set that array to 'handlers'. Otherwise,
// set 'handlers' to an empty array.
handlers = currentElement.__handlers
&& currentElement.__handlers[ev.type]
&& currentElement.__handlers[ev.type].capture
|| [];
ev.currentTarget = currentElement;
// Loop through the handlers we've collected and
// execute them in the context of the current element
for(var h = 0; i < handlers.length; h++){
handlers[h].call(currentElement, ev);
}
}
// Step 4: Execute DOM Level 1 event handler
// If propagation was not stopped, execute
// the DOM level 1 event handler
if(!isPropagationStopped){
ev.target["on" + ev.type].call(ev.target, ev);
}
elements.reverse();
ev.eventPhase = 1;
// Step 5: Execute Bubble Phase handlers
// Basically, do the same thing as before,
// but with the 'elements' list reversed...
for(var i = 0 ; i < elements.length; i++){
if(isPropagationStopped){
break;
}
// ... Also, we are working with the 'bubble' phase
// this time, not 'capture'
var currentElement = elements[i],
handlers = currentElement.__handlers
&& currentElement.__handlers[ev.type]
&& currentElement.__handlers[ev.type].bubble
|| [];
ev.currentTarget = currentElement;
for(var h = 0 ; i < handlers.length; h++){
handlers[h].call(currentElement,ev);
}
}
// Step 6: Execute default browser behavior
// Default behaviors for HTML elements
if(!isDefaultPrevented){
// anchor tag (a link)
if(ev.type == "click"
&& ev.target.nodeName.toLowerCase() == "a"){
window.location = ev.target.href;
}
// default cases for the rest of the elements go here...
// (submit, etc.)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment