Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Event Listener polyfill
// addEventListener polyfill IE6+
!window.addEventListener && (function (window, document) {
function Event(e, element) {
var instance = this;
for (property in e) {
instance[property] = e[property];
}
instance.currentTarget = element;
instance.target = e.srcElement || element;
instance.timeStamp = +new Date;
instance.preventDefault = function () {
e.returnValue = false;
};
instance.stopPropagation = function () {
e.cancelBubble = true;
};
}
function addEventListener(type, listener) {
var
element = this,
listeners = element.listeners = element.listeners || [],
index = listeners.push([listener, function (e) {
listener.call(element, new Event(e, element));
}]) - 1;
element.attachEvent('on' + type, listeners[index][1]);
}
function removeEventListener(type, listener) {
for (var element = this, listeners = element.listeners || [], length = listeners.length, index = 0; index < length; ++index) {
if (listeners[index][0] === listener) {
element.detachEvent('on' + type, listeners[index][1]);
}
}
}
window.addEventListener = document.addEventListener = addEventListener;
window.removeEventListener = document.removeEventListener = removeEventListener;
if ('Element' in window) {
Element.prototype.addEventListener = addEventListener;
Element.prototype.removeEventListener = removeEventListener;
} else {
var
head = document.getElementsByTagName('head')[0],
style = document.createElement('style');
head.insertBefore(style, head.firstChild);
style.styleSheet.cssText = '*{-ms-event-prototype:expression(!this.addEventListener&&(this.addEventListener=addEventListener)&&(this.removeEventListener=removeEventListener))}';
}
})(window, document) && scrollBy(0, 0);
@matthewp

This comment has been minimized.

Show comment Hide comment
@matthewp

matthewp Jul 5, 2012

This won't work when the listener is an object. In that case addEventListener will call listener.handleEvent. Should be easy enough to fix though. Here's an explanation:

http://ajaxian.com/archives/an-alternative-way-to-addeventlistener

matthewp commented Jul 5, 2012

This won't work when the listener is an object. In that case addEventListener will call listener.handleEvent. Should be easy enough to fix though. Here's an explanation:

http://ajaxian.com/archives/an-alternative-way-to-addeventlistener

@Rich-Harris

This comment has been minimized.

Show comment Hide comment
@Rich-Harris

Rich-Harris Jul 16, 2013

Thanks for this polyfill - the CSS expression stuff is a stroke of genius. I've forked it to use it in a project of my own (you don't specify a license but I assume that's kosher...).

There's one bit I don't quite understand: what's up with scrollBy(0, 0)? The IIFE returns undefined, so the && operator short-circuits and the code is never reached. What does it do?

Thanks for this polyfill - the CSS expression stuff is a stroke of genius. I've forked it to use it in a project of my own (you don't specify a license but I assume that's kosher...).

There's one bit I don't quite understand: what's up with scrollBy(0, 0)? The IIFE returns undefined, so the && operator short-circuits and the code is never reached. What does it do?

@carlosascari

This comment has been minimized.

Show comment Hide comment
@carlosascari

carlosascari Feb 18, 2016

Keep in mind, for...in loops are supported by IE10+. So this polyfill will not work unless you replace then with normal for(;;) loops.

Keep in mind, for...in loops are supported by IE10+. So this polyfill will not work unless you replace then with normal for(;;) loops.

@paulyn000

This comment has been minimized.

Show comment Hide comment
@paulyn000

paulyn000 Mar 20, 2016

will this work on DOMContentLoaded, readystatechange, progress or what?

will this work on DOMContentLoaded, readystatechange, progress or what?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment