現代瀏覽器監聽事件使用addEventListener函數,解除綁定監聽使用removeEventListener函數。但是ie7、ie8監聽事件使用attachEvent函數,解除監聽事件使用detachEvent函數。 簡單的相容函數: addEventListener綁定的監聽事件,事件內th ...
現代瀏覽器監聽事件使用addEventListener函數,解除綁定監聽使用removeEventListener函數。但是ie7、ie8監聽事件使用attachEvent函數,解除監聽事件使用detachEvent函數。
簡單的相容函數:
1 if(document.addEventListener){ 2 element.addEventListener(type, fun, useCapture); 3 }else{ 4 element.addEventListener("on" + type, fun); 5 }
addEventListener綁定的監聽事件,事件內this指向element。但是attachEvent綁定的監聽事件,事件內this指向window,使用call或者apply可以解決該問題,修改this指向element,event作為參數傳遞。
1 var addListener = (function(){ 2 if(document.addEventListener){ 3 return function(element, type, fun, useCapture){ 4 element.addEventListener(type, fun, useCapture ? useCapture : false); 5 }; 6 }else{ 7 return function(element, type, fun){ 8 element.attachEvent("on" + type, function(event){ 9 fun.call(element, event); 10 }); 11 }; 12 } 13 })();
但是這樣也有個問題,就是detachEvent無法解除監聽,因為傳遞的事件已經改變了。通過function.prototype將修改後的函數和已經綁定該事件的dom儲存起來,可以使detachEvent時能獲取到解除監聽的函數,addEventListener自己會避免多次綁定一個事件,attachEvent需要自己判斷是否綁定多次事件。
1 /** 2 * addEventlistener相容函數 3 * ie9以上正常使用addEventlistener函數 4 * ie7、ie8用傳遞的function的function.prototype儲存經過處理的事件 5 * function.prototype["_" + type]:記錄處理後的信息 6 * function.prototype["_" + type]._function <function>:經過處理的事件 7 * function.prototype["_" + type]._element <array> :已經綁定的dom 8 */ 9 10 /*** addEventlistener ***/ 11 var addListener = (function(){ 12 if(document.addEventListener){ 13 /* ie9以上正常使用addEventListener */ 14 return function(element, type, fun, useCapture){ 15 element.addEventListener(type, fun, useCapture ? useCapture : false); 16 }; 17 }else{ 18 /* ie7、ie8使用attachEvent */ 19 return function(element, type, fun){ 20 if(!fun.prototype["_" + type]){ 21 /* 該事件第一次綁定 */ 22 fun.prototype["_" + type] = { 23 _function: function(event){ 24 fun.call(element, event); 25 }, 26 _element: [element] 27 }; 28 element.attachEvent("on" + type, fun.prototype["_" + type]._function); 29 }else{ 30 /* 該事件被綁定過 */ 31 var s = true; 32 // 判斷當前的element是否已經綁定過該事件 33 for(var i in fun.prototype["_" + type]._element){ 34 if(fun.prototype["_" + type]._element[i] === element){ 35 s = false; 36 break; 37 } 38 } 39 // 當前的element沒有綁定過該事件 40 if(s === true){ 41 element.attachEvent("on" + type, fun.prototype["_" + type]._function); 42 fun.prototype["_" + type]._element.push(element); 43 } 44 } 45 }; 46 } 47 })(); 48 /*** removeEventlistener ***/ 49 var removeListener = (function(){ 50 if(document.addEventListener){ 51 /* ie9以上正常使用removeEventListener */ 52 return function(element, type, fun){ 53 element.removeEventListener(type, fun); 54 }; 55 }else{ 56 /* ie7、ie8使用detachEvent */ 57 return function(element, type, fun){ 58 element.detachEvent("on" + type, fun.prototype["_" + type]._function); 59 if(fun.prototype["_" + type]._element.length === 1){ 60 // 該事件只有一個element監聽,刪除function.prototype["_" + type] 61 delete fun.prototype["_" + type]; 62 }else{ 63 // 該事件只有多個element監聽,從function.prototype["_" + type]._element數組中刪除該element 64 for(var i in fun.prototype["_" + type]._element){ 65 if(fun.prototype["_" + type]._element[i] === element){ 66 fun.prototype["_" + type]._element.splice(i, 1); 67 break; 68 } 69 } 70 } 71 }; 72 } 73 })();