├── eventListenerIEPolyfill.min.js ├── README.md └── eventListenerIEPolyfill.js /eventListenerIEPolyfill.min.js: -------------------------------------------------------------------------------- 1 | !function(e,t,n){if((!e.addEventListener||!e.removeEventListener)&&e.attachEvent&&e.detachEvent){var r=function(e){return"function"==typeof e},a=function(e,t){var r=t[n];if(r)for(var a,i=r.length;i--;)if(a=r[i],a[0]===e)return a[1]},i=function(e,t,r){var i=t[n]||(t[n]=[]);return a(e,t)||(i[i.length]=[e,r],r)},o=function(e){var n=t[e];t[e]=function(e){return u(n(e))}},v=function(n,a){if(r(a)){var o=this;o.attachEvent("on"+n,i(o,a,function(n){n=n||e.event,n.preventDefault=n.preventDefault||function(){n.returnValue=!1},n.stopPropagation=n.stopPropagation||function(){n.cancelBubble=!0},n.target=n.target||n.srcElement||t.documentElement,n.currentTarget=n.currentTarget||o,n.timeStamp=n.timeStamp||(new Date).getTime(),a.call(o,n)}))}},c=function(e,t){if(r(t)){var n=this,i=a(n,t);i&&n.detachEvent("on"+e,i)}},u=function(e){var t=e.length;if(t)for(;t--;)e[t].addEventListener=v,e[t].removeEventListener=c;else e.addEventListener=v,e.removeEventListener=c;return e};if(u([t,e]),"Element"in e){var f=e.Element;f.prototype.addEventListener=v,f.prototype.removeEventListener=c}else t.attachEvent("onreadystatechange",function(){u(t.all)}),o("getElementsByTagName"),o("getElementById"),o("createElement"),u(t.all)}}(window,document,"x-ms-event-listeners"); 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | eventListenerPolyfill 2 | ===================== 3 | IE6-IE8 Polyfill for missing `addEventListener` and `removeEventListener` Javascript methods. 4 | 5 | This Polyfill allows a standard way for most browsers to manage event listeners. The lack of standard implementation makes tasks such as executing Javascript after a page is loaded difficult. This Polyfill relies on IE6-IE8's `attachEvent` and `detectEvent` which is why it only works for these browsers. 6 | 7 | This project origins from : 8 | 9 | * https://gist.github.com/2864711/946225eb3822c203e8d6218095d888aac5e1748e (original proposal/idea) 10 | * http://qiita.com/sounisi5011/items/a8fc80e075e4f767b79a#11 (2014 remake) 11 | 12 | The second version has not had a lot visibility given it was hosted on a Japanese website. This repository has been setup so that more people can contribute to this Polyfill. 13 | 14 | _This script is stand alone and does not required any external library._ 15 | 16 | ### Size 17 | 18 | - Full version: 5k 19 | - Minified: 1.2k 20 | - Minified & Compressed: 0.8k 21 | 22 | ### Supports 23 | - Browsers: IE6-IE8 (all other browsers will ignore the script) 24 | - Scope: useCapture is not supported when using the Polyfill 25 | - Limitations: Could potentially not play nice with JQuery and other scripts with similar features. 26 | 27 | ### Usage 28 | 29 | Simply load this script in your HTML code and use the `addEventListener` and `removeEventListener` methods. 30 | 31 | Example 32 | 33 | 1) Add the script on your page: 34 | 35 | ```html 36 | 37 | ``` 38 | 39 | 2) Try your new methods on old browsers: 40 | 41 | ```javascript 42 | // Example with an object. 43 | var helloWorld = function () {alert('hello world');}; 44 | window.addEventListener('load', helloWorld); 45 | 46 | // Example passing an argument. 47 | var say = function (something) {alert('You said ' + something);}; 48 | window.addEventListener('load', function () {say('hello world')}); 49 | ``` 50 | 51 | 3) You're done. 52 | -------------------------------------------------------------------------------- /eventListenerIEPolyfill.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @license addEventListener polyfill 1.0 / Eirik Backer / MIT Licence 3 | * https://gist.github.com/2864711/946225eb3822c203e8d6218095d888aac5e1748e 4 | * 5 | * sounisi5011 version: 6 | * http://qiita.com/sounisi5011/items/a8fc80e075e4f767b79a#11 7 | */ 8 | (function (window, document, listeners_prop_name) { 9 | if ((!window.addEventListener || !window.removeEventListener) && window.attachEvent && window.detachEvent) { 10 | /** 11 | * @param {*} value 12 | * @return {boolean} 13 | */ 14 | var is_callable = function (value) { 15 | return typeof value === 'function'; 16 | }; 17 | /** 18 | * @param {!Window|HTMLDocument|Node} self 19 | * @param {EventListener|function(!Event):(boolean|undefined)} listener 20 | * @return {!function(Event)|undefined} 21 | */ 22 | var listener_get = function (self, listener) { 23 | var listeners = listener[listeners_prop_name]; 24 | if (listeners) { 25 | var lis; 26 | var i = listeners.length; 27 | while (i--) { 28 | lis = listeners[i]; 29 | if (lis[0] === self) { 30 | return lis[1]; 31 | } 32 | } 33 | } 34 | }; 35 | /** 36 | * @param {!Window|HTMLDocument|Node} self 37 | * @param {EventListener|function(!Event):(boolean|undefined)} listener 38 | * @param {!function(Event)} callback 39 | * @return {!function(Event)} 40 | */ 41 | var listener_set = function (self, listener, callback) { 42 | var listeners = listener[listeners_prop_name] || (listener[listeners_prop_name] = []); 43 | return listener_get(self, listener) || (listeners[listeners.length] = [self, callback], callback); 44 | }; 45 | /** 46 | * @param {string} methodName 47 | */ 48 | var docHijack = function (methodName) { 49 | var old = document[methodName]; 50 | document[methodName] = function (v) { 51 | return addListen(old(v)); 52 | }; 53 | }; 54 | /** 55 | * @this {!Window|HTMLDocument|Node} 56 | * @param {string} type 57 | * @param {EventListener|function(!Event):(boolean|undefined)} listener 58 | * @param {boolean=} useCapture 59 | */ 60 | var addEvent = function (type, listener, useCapture) { 61 | if (is_callable(listener)) { 62 | var self = this; 63 | self.attachEvent( 64 | 'on' + type, 65 | listener_set(self, listener, function (e) { 66 | e = e || window.event; 67 | e.preventDefault = e.preventDefault || function () { e.returnValue = false }; 68 | e.stopPropagation = e.stopPropagation || function () { e.cancelBubble = true }; 69 | e.target = e.target || e.srcElement || document.documentElement; 70 | e.currentTarget = e.currentTarget || self; 71 | e.timeStamp = e.timeStamp || (new Date()).getTime(); 72 | listener.call(self, e); 73 | }) 74 | ); 75 | } 76 | }; 77 | /** 78 | * @this {!Window|HTMLDocument|Node} 79 | * @param {string} type 80 | * @param {EventListener|function(!Event):(boolean|undefined)} listener 81 | * @param {boolean=} useCapture 82 | */ 83 | var removeEvent = function (type, listener, useCapture) { 84 | if (is_callable(listener)) { 85 | var self = this; 86 | var lis = listener_get(self, listener); 87 | if (lis) { 88 | self.detachEvent('on' + type, lis); 89 | } 90 | } 91 | }; 92 | /** 93 | * @param {!Node|NodeList|Array} obj 94 | * @return {!Node|NodeList|Array} 95 | */ 96 | var addListen = function (obj) { 97 | var i = obj.length; 98 | if (i) { 99 | while (i--) { 100 | obj[i].addEventListener = addEvent; 101 | obj[i].removeEventListener = removeEvent; 102 | } 103 | } else { 104 | obj.addEventListener = addEvent; 105 | obj.removeEventListener = removeEvent; 106 | } 107 | return obj; 108 | }; 109 | 110 | addListen([document, window]); 111 | if ('Element' in window) { 112 | /** 113 | * IE8 114 | */ 115 | var element = window.Element; 116 | element.prototype.addEventListener = addEvent; 117 | element.prototype.removeEventListener = removeEvent; 118 | } else { 119 | /** 120 | * IE < 8 121 | */ 122 | //Make sure we also init at domReady 123 | document.attachEvent('onreadystatechange', function () { addListen(document.all) }); 124 | docHijack('getElementsByTagName'); 125 | docHijack('getElementById'); 126 | docHijack('createElement'); 127 | addListen(document.all); 128 | } 129 | } 130 | })(window, document, 'x-ms-event-listeners'); 131 | --------------------------------------------------------------------------------