Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
Polyfill the EventListener interface in IE8

EventListener Polyfill

Is IE8 your new IE6? Level the playing field with polyfills.

This script polyfills addEventListener, removeEventListener, and dispatchEvent. It is less than half a kilobyte minified and gzipped.

addEventListener

addEventListener registers a single event listener on a single target.

Syntax

target.addEventListener(type, listener);

type: A string representing the event type to listen for.

listener: The object that receives a notification when an event of the specified type occurs. This must be an object implementing the EventListener interface, or simply a JavaScript function.

It should be noted that useCapture has not been polyfilled.

removeEventListener

removeEventListener unregisters a single event listener on a single target.

Syntax

target.removeEventListener(type, listener);

type: A string representing the event type being removed.

listener: The EventListener object or function to be removed.

It should be noted that useCapture has not been polyfilled.

dispatchEvent

Dispatches an event into the event system. The event is subject to the same capturing and bubbling behavior as directly dispatched events.

Syntax

bool = target.dispatchEvent(event);

event: An event object to be dispatched.

It should be noted that document.createEvent has not been polyfilled.

!window.addEventListener && (function (WindowPrototype, DocumentPrototype, ElementPrototype, addEventListener, removeEventListener, dispatchEvent, registry) {
WindowPrototype[addEventListener] = DocumentPrototype[addEventListener] = ElementPrototype[addEventListener] = function (type, listener) {
var target = this;
registry.unshift([target, type, listener, function (event) {
event.currentTarget = target;
event.preventDefault = function () { event.returnValue = false };
event.stopPropagation = function () { event.cancelBubble = true };
event.target = event.srcElement || target;
listener.call(target, event);
}]);
this.attachEvent("on" + type, registry[0][3]);
};
WindowPrototype[removeEventListener] = DocumentPrototype[removeEventListener] = ElementPrototype[removeEventListener] = function (type, listener) {
for (var index = 0, register; register = registry[index]; ++index) {
if (register[0] == this && register[1] == type && register[2] == listener) {
return this.detachEvent("on" + type, registry.splice(index, 1)[0][3]);
}
}
};
WindowPrototype[dispatchEvent] = DocumentPrototype[dispatchEvent] = ElementPrototype[dispatchEvent] = function (eventObject) {
return this.fireEvent("on" + eventObject.type, eventObject);
};
})(Window.prototype, HTMLDocument.prototype, Element.prototype, "addEventListener", "removeEventListener", "dispatchEvent", []);
!window.addEventListener&&function(e,t,n,r,i,s,o){e[r]=t[r]=n[r]=function(e,t){var n=this;o.unshift([n,e,t,function(e){e.currentTarget=n,e.preventDefault=function(){e.returnValue=!1},e.stopPropagation=function(){e.cancelBubble=!0},e.target=e.srcElement||n,t.call(n,e)}]),this.attachEvent("on"+e,o[0][3])},e[i]=t[i]=n[i]=function(e,t){for(var n=0,r;r=o[n];++n)if(r[0]==this&&r[1]==e&&r[2]==t)return this.detachEvent("on"+e,o.splice(n,1)[0][3])},e[s]=t[s]=n[s]=function(e){return this.fireEvent("on"+e.type,e)}}(Window.prototype,HTMLDocument.prototype,Element.prototype,"addEventListener","removeEventListener","dispatchEvent",[])
@MoOx

This comment has been minimized.

Show comment Hide comment
@MoOx

MoOx Mar 12, 2013

Just to let you know, the awesome aight.js now use this polyfill :)
Thanks for this one !

MoOx commented Mar 12, 2013

Just to let you know, the awesome aight.js now use this polyfill :)
Thanks for this one !

@Extramez

This comment has been minimized.

Show comment Hide comment
@Extramez

Extramez Jul 9, 2015

Можно оптимизировать работу функций таким образом:
//registry = {};

//newEvent :::
var array = registry[type]||(registry[type] = new Array());
array.pop([tagret, listener, function(){.................}]);
this.attachEvent(type, array[array.length-1][2]);

//delEvent::
for(var i=0,sl=registry[type];sl&&sl[i];i++){
if(sl[i][0]===this&&sl[i][2]===func) return this.detachEvent(ev, sl.splice(i,1)[0][3]);
}

Это принесет как минимум два плюса:

  1. Метод pop() работает быстрее метода unshift()
  2. При удалении события не нужно будет перебирать registry, в которой может быть огромное кол-во событий, а можно будет сразу обратится к registry[type] и вот там уже провести поиск.

Extramez commented Jul 9, 2015

Можно оптимизировать работу функций таким образом:
//registry = {};

//newEvent :::
var array = registry[type]||(registry[type] = new Array());
array.pop([tagret, listener, function(){.................}]);
this.attachEvent(type, array[array.length-1][2]);

//delEvent::
for(var i=0,sl=registry[type];sl&&sl[i];i++){
if(sl[i][0]===this&&sl[i][2]===func) return this.detachEvent(ev, sl.splice(i,1)[0][3]);
}

Это принесет как минимум два плюса:

  1. Метод pop() работает быстрее метода unshift()
  2. При удалении события не нужно будет перебирать registry, в которой может быть огромное кол-во событий, а можно будет сразу обратится к registry[type] и вот там уже провести поиск.
@decebal

This comment has been minimized.

Show comment Hide comment
@decebal

decebal Oct 28, 2015

@Extramez, great suggestion, but why not English ?

decebal commented Oct 28, 2015

@Extramez, great suggestion, but why not English ?

@alexcroox

This comment has been minimized.

Show comment Hide comment
@alexcroox

alexcroox Sep 20, 2017

"Object doesn't support this action" in IE8 for listener.call(target, event);

"Object doesn't support this action" in IE8 for listener.call(target, event);

@TViT

This comment has been minimized.

Show comment Hide comment
@TViT

TViT Sep 28, 2017

Extramez спасибо! Голова!

TViT commented Sep 28, 2017

Extramez спасибо! Голова!

@Worthy7

This comment has been minimized.

Show comment Hide comment
@Worthy7

Worthy7 Dec 7, 2017

I am also getting "Object doesn't support this action" in IE8 for listener.call(target, event); @alexcroox did you solve it?

Worthy7 commented Dec 7, 2017

I am also getting "Object doesn't support this action" in IE8 for listener.call(target, event); @alexcroox did you solve it?

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