From f67705f4c95eb75b3aa0bf7cbe2b5175a9644a59 Mon Sep 17 00:00:00 2001 From: Jonas Smedegaard Date: Wed, 9 Sep 2015 03:25:56 +0200 Subject: Initial draft. --- EventListener.js | 125 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 125 insertions(+) create mode 100644 EventListener.js (limited to 'EventListener.js') diff --git a/EventListener.js b/EventListener.js new file mode 100644 index 0000000..fa3423b --- /dev/null +++ b/EventListener.js @@ -0,0 +1,125 @@ +// EventListener | MIT/GPL2 | github.com/jonathantneal/EventListener + +this.Element && Element.prototype.attachEvent && !Element.prototype.addEventListener && (function () { + function addToPrototype(name, method) { + Window.prototype[name] = HTMLDocument.prototype[name] = Element.prototype[name] = method; + } + + // add + addToPrototype("addEventListener", function (type, listener) { + var + target = this, + listeners = target.addEventListener.listeners = target.addEventListener.listeners || {}, + typeListeners = listeners[type] = listeners[type] || []; + + // if no events exist, attach the listener + if (!typeListeners.length) { + target.attachEvent("on" + type, typeListeners.event = function (event) { + var documentElement = target.document && target.document.documentElement || target.documentElement || { scrollLeft: 0, scrollTop: 0 }; + + // polyfill w3c properties and methods + event.currentTarget = target; + event.pageX = event.clientX + documentElement.scrollLeft; + event.pageY = event.clientY + documentElement.scrollTop; + event.preventDefault = function () { event.returnValue = false }; + event.relatedTarget = event.fromElement || null; + event.stopImmediatePropagation = function () { immediatePropagation = false; event.cancelBubble = true }; + event.stopPropagation = function () { event.cancelBubble = true }; + event.target = event.srcElement || target; + event.timeStamp = +new Date; + + // create an cached list of the master events list (to protect this loop from breaking when an event is removed) + for (var i = 0, typeListenersCache = [].concat(typeListeners), typeListenerCache, immediatePropagation = true; immediatePropagation && (typeListenerCache = typeListenersCache[i]); ++i) { + // check to see if the cached event still exists in the master events list + for (var ii = 0, typeListener; typeListener = typeListeners[ii]; ++ii) { + if (typeListener == typeListenerCache) { + typeListener.call(target, event); + + break; + } + } + } + }); + } + + // add the event to the master event list + typeListeners.push(listener); + }); + + // remove + addToPrototype("removeEventListener", function (type, listener) { + var + target = this, + listeners = target.addEventListener.listeners = target.addEventListener.listeners || {}, + typeListeners = listeners[type] = listeners[type] || []; + + // remove the newest matching event from the master event list + for (var i = typeListeners.length - 1, typeListener; typeListener = typeListeners[i]; --i) { + if (typeListener == listener) { + typeListeners.splice(i, 1); + + break; + } + } + + // if no events exist, detach the listener + if (!typeListeners.length && typeListeners.event) { + target.detachEvent("on" + type, typeListeners.event); + } + }); + + // dispatch + addToPrototype("dispatchEvent", function (eventObject) { + var + target = this, + type = eventObject.type, + listeners = target.addEventListener.listeners = target.addEventListener.listeners || {}, + typeListeners = listeners[type] = listeners[type] || []; + + try { + return target.fireEvent("on" + type, eventObject); + } catch (error) { + if (typeListeners.event) { + typeListeners.event(eventObject); + } + + return; + } + }); + + // CustomEvent + Object.defineProperty(Window.prototype, "CustomEvent", { + get: function () { + var self = this; + + return function CustomEvent(type, eventInitDict) { + var event = self.document.createEventObject(), key; + + event.type = type; + for (key in eventInitDict) { + if (key == 'cancelable'){ + event.returnValue = !eventInitDict.cancelable; + } else if (key == 'bubbles'){ + event.cancelBubble = !eventInitDict.bubbles; + } else if (key == 'detail'){ + event.detail = eventInitDict.detail; + } + } + return event; + }; + } + }); + + // ready + function ready(event) { + if (ready.interval && document.body) { + ready.interval = clearInterval(ready.interval); + + document.dispatchEvent(new CustomEvent("DOMContentLoaded")); + } + } + + ready.interval = setInterval(ready, 1); + + window.addEventListener("load", ready); +})(); -- cgit v1.2.3