事件綁定(終極版)

內容提綱:數組

1.問題所在瀏覽器

2.設置代碼函數

發文不易,轉載註明出處!this

 

1.問題所在spa

現代綁定中W3C使用的是:addEventListener和removeEventListener。IE使用的是attachEvent和detachEvent。咱們知道IE的這兩個問題多多,而且伴隨內存泄漏。因此,解決這些問題很是有必要。code

那麼咱們但願解決非IE瀏覽器事件綁定哪些問題呢?對象

1.支持同一元素的同一事件句柄能夠綁定多個監聽函數;blog

2.若是在同一元素的同一事件句柄上屢次註冊同一函數,那麼第一次註冊後的全部註冊都被忽略;事件

3.函數體內的this指向的應當是正在處理事件的節點(如當前正在運行事件句柄的節點);內存

4.監聽函數的執行順序應當是按照綁定的順序執行;

5.在函數體內不用使用 event = event || window.event; 來標準化Event對象;

咱們嘗試着經過使用傳統事件綁定對IE進行封裝。

 

2.設置代碼

 1 //跨瀏覽器添加事件綁定
 2 
 3 function addEvent(obj, type, fn) {  4 
 5        if (typeof obj.addEventListener != 'undefined') {  6 
 7               obj.addEventListener(type, fn, false);  8 
 9        } else {  10 
 11               //建立事件類型的散列表(哈希表)
 12 
 13               if (!obj.events) obj.events = {};  14 
 15               //建立存放事件處理函數的數組
 16 
 17               if (!obj.events[type]) {  18 
 19                      obj.events[type] = []; 28 
 29                      //執行事件處理
 30 
 31                      obj['on' + type] = addEvent.exec;  32 
 33               } else {  34 
 35                      //同一個註冊函數取消計數
 36 
 37                      if (addEvent.array(fn,obj.events[type])) return false;  38 
 39  }  40 
 41               //經過計數器存儲
 42 
 43               obj.events[type][addEvent.ID++] = fn;  44 
 45  }  46 
 47 }  48 
 49  
 50 
 51 addEvent.array = function (fn, es){  52 
 53        for (var i in es) {  54 
 55               if (es[i] == fn) return true;  56 
 57  }  58 
 59        return false;  60 
 61 }  62 
 63  
 64 
 65 //每一個事件處理函數的ID計數器
 66 
 67 addEvent.ID = 0;  68 
 69  
 70 
 71 //事件處理函數調用
 72 
 73 addEvent.exec = function (event) {  74 
 75        var e = event || addEvent.fixEvent(window.event);  76 
 77        var es = this.events[e.type];  78 
 79        for (var i in es) {  80 
 81               es[i].call(this, e);  82 
 83  }  84 
 85 };  86 
 87  
 88 
 89 //獲取IE的event,兼容W3C的調用
 90 
 91 addEvent.fixEvent = function (event) {  92   //爲event添加preventDefault方法
 93        event.preventDefault = addEvent.fixEvent.preventDefault;
 95        event.stopPropagation = addEvent.fixEvent.stopPropagation;  96 
 97        return event;  98 
 99 }; 100 
101  
102 
103 //兼容IE和W3C阻止默認行爲
104 
105 addEvent.fixEvent.preventDefault = function () { 106 
107        this.returnValue = false; 108 
109 }; 110 
111  
112 
113 //兼容IE和W3C取消冒泡
114 
115 addEvent.fixEvent.stopPropagation = function () { 116 
117        this.cancelBubble = true; 118 
119 }; 120 
121  
122 
123 //跨瀏覽器刪除事件
124 
125 function removeEvent(obj, type, fn) { 126 
127        if (typeof obj.removeEventListener != 'undefined') { 128 
129               obj.removeEventListener(type, fn, false); 130 
131        } else { 132 
133               var es = obj.events[type]; 134 
135               for (var i in es) { 136 
137                      if (es[i] == fn) { 138 
139                             delete obj.events[type][i]; 140 
141  } 142 
143  } 144 
145  } 146 
147 }
相關文章
相關標籤/搜索