又是一個重磅功能點。
在分析源碼之前分析一下體系結構,有助于源碼理解。實際上在jQuery出現之前,Dean Edwards的跨瀏覽器AddEvent()設計做的已經比較優秀了;而且jQuery事件系統的設計思想也是基于該思想的,所以我們先分析一下Dean Edwards前輩的事件綁定。
源碼解讀

//事件添加方法function addEvent(element, type, handler) { //保證每個不同的事件響應函數只有唯一一個id if (!handler.$$guid) handler.$$guid = addEvent.guid++; // 給element維護一個events屬性,初始化為一個空對象。 // element.events的結構類似于 { "click": {...}, "dbclick": {...}, "change": {...} } if (!element.events) element.events = {}; // 試圖取出element.events中當前事件類型type對應的對象(這個對象更像數組),賦值給handlers //如果element.events中沒有當前事件類型type對應的對象則初始化 var handlers = element.events[type]; if (!handlers) { handlers = element.events[type] = {}; // 如果這個element已經有了一個對應的事件的響應方法,例如已經有了onclick方法 // 就把element的onclick方法賦值給handlers的0元素,此時handlers的結構就是: // { 0: function(e){...} },這也是為什么addEvent.guid初始化為1的原因,預留看為0的空間; // 此時element.events的結構就是: { "click": { 0: function(e){...} }, /*省略其他事件類型*/ } if (element["on" + type]) { handlers[0] = element["on" + type]; } } // 把當前的事件handler存放到handlers中,handler.$$guid = addEvent.guid++; addEvent.guid = 1; 肯定是從1開始累加的 //因此,這是handlers的結構可能就是 { 0: function(e){...}, 1: function(){}, 2: function(){} 等等... } handlers[handler.$$guid] = handler; //下文定義了一個handleEvent(event)函數,將這個函數,綁定到element的type事件上作為事件入口。 //說明:在element進行click時,將會觸發handleEvent函數,handleEvent函數將會查找element.events,并調用相應的函數。可以把handleEvent稱為“主監聽函數” element["on" + type] = handleEvent;}; //計數器addEvent.guid = 1; function removeEvent(element, type, handler) { // delete the event handler from the hash table if (element.events && element.events[type]) { delete element.events[type][handler.$$guid]; }}; function handleEvent(event) { //兼容ie event = event || window.event; //this是響應事件的節點,這個接點上有events屬性(在addEvent中添加的) //獲取節點對應事件響應函數列表 var handlers = this.events[event.type]; // 循環響應函數列表執行 for (var i in handlers) { //保持正確的作用域,即this關鍵字 this.$$handleEvent = handlers[i]; this.$$handleEvent(event); }};
新聞熱點
疑難解答