|
window.cbef = (function() { |
|
// written by Dean Edwards, 2005 |
|
// with input from Tino Zijdel - [email protected] |
|
// with input from Carl Sverre - [email protected] |
|
// http://dean.edwards.name/weblog/2005/10/add-event/ |
|
|
|
var exports = {} |
|
, cbefHandlerStr = "__cbefHandler" |
|
, handleEventStr = "__handleEvent"; |
|
|
|
// oldSchool is optional, if it is true then we won't use addEventListener |
|
exports.addEvent = function(element, type, handler, oldSchool) { |
|
if (element.addEventListener && !oldSchool) { |
|
element.addEventListener(type, handler, false); |
|
} else { |
|
if (!handler.$$guid) { handler.$$guid = exports.addEvent.guid++; } |
|
if (!element.events) { element.events = {}; } |
|
|
|
var handlers = element.events[type] |
|
, ontype = 'on' + type; |
|
|
|
if (!handlers) { handlers = element.events[type] = {}; } |
|
|
|
if (element[ontype] && !element[ontype][cbefHandlerStr]) { |
|
handlers[exports.addEvent.guid++] = element[ontype]; |
|
element[ontype] = makeHandler(element); |
|
} else if (!element[ontype]) { |
|
element[ontype] = makeHandler(element); |
|
} |
|
|
|
handlers[handler.$$guid] = handler; |
|
} |
|
}; |
|
exports.addEvent.guid = 1; |
|
|
|
// oldSchool is optional, if it is true then we won't use addEventListener |
|
exports.removeEvent = function(element, type, handler, oldSchool) { |
|
if (element.removeEventListener && !oldSchool) { |
|
element.removeEventListener(type, handler, false); |
|
} else if (element.events && element.events[type] && handler.$$guid) { |
|
delete element.events[type][handler.$$guid]; |
|
} |
|
}; |
|
|
|
// ensure handleEvent is called with the element as the context |
|
function makeHandler(element) { |
|
element[handleEventStr] = handleEvent; |
|
var func = function(e) { return element[handleEventStr](e); }; |
|
func[cbefHandlerStr] = true; |
|
return func; |
|
}; |
|
|
|
function handleEvent(event) { |
|
event = event || fixEvent(window.event); |
|
var returnValue = true; |
|
var handlers = this.events[event.type]; |
|
|
|
for (var i in handlers) { |
|
if (!Object.prototype[i]) { |
|
this.$$handler = handlers[i]; |
|
if (this.$$handler(event) === false) { returnValue = false; } |
|
} |
|
} |
|
|
|
if (this.$$handler) { this.$$handler = null; } |
|
|
|
return returnValue; |
|
}; |
|
|
|
function fixEvent(event) { |
|
event.preventDefault = fixEvent.preventDefault; |
|
event.stopPropagation = fixEvent.stopPropagation; |
|
return event; |
|
}; |
|
fixEvent.preventDefault = function() { |
|
this.returnValue = false; |
|
}; |
|
fixEvent.stopPropagation = function() { |
|
this.cancelBubble = true; |
|
}; |
|
|
|
// This little snippet fixes the problem that the onload attribute on the body-element will overwrite |
|
// previous attached events on the window object for the onload event |
|
document.onreadystatechange = function() { |
|
if (window.onload && !window.onload[cbefHandlerStr]) { |
|
exports.addEvent(window, 'load', window.onload, true); |
|
} |
|
} |
|
|
|
return exports; |
|
}()); |