關於事件部分,我思考了好久,也參考了許多,到底如何能用一個很簡單的方法實現如出一轍的on、off呢?javascript
最後個人設計思路是:java
1.有一個全局存儲全部
Events
的數組,存放每一個dom
元素上的事件。git2.給每一個
DOM
一個guid
的惟一標識符,經過這個guid
來找出Events
數組裏的事件。github
因爲邏輯比較複雜,咱們先來畫個圖看看。segmentfault
首先,咱們利用DOM能夠增長自定義屬性的原理,在它的身上存一個guid。數組
以後整個事件機制就根據這個guid來進行查找與存儲。less
接下來是代碼部分dom
Kodo.Events = []; //事件綁定存放的事件 Kodo.guid = 0; //事件綁定的惟一標識 on: function(type, selector, fn) { if (typeof selector == 'function') { fn = selector; //兩個參數的狀況 for (var i = 0; i < this.length; i++) { if (!this[i].guid) { this[i].guid = ++Kodo.guid; //guid 不存在,給當前dom一個guid Kodo.Events[Kodo.guid] = {}; /* *給Events[guid] 開闢一個新對象 *用於存儲這個dom上的全部事件方法 */ Kodo.Events[Kodo.guid][type] = [fn]; //每一個方法都是一個數組 //給這個新對象,賦予事件數組 "click" : [fn1,fn2,...] bind(this[i], type, this[i].guid);//綁定事件 } else {//guid存在的狀況 var id = this[i].guid; if (Kodo.Events[id][type]) { //若是這存在是當前事件已經存過,不用在綁定事件,直接放入方法數組便可 Kodo.Events[id][type].push(fn); } else { //這是存新事件,因此須要從新綁定一次 Kodo.Events[id][type] = [fn]; bind(this[i], type, id); } } } } } function bind(dom, type, guid) { dom.addEventListener(type, function(e) { //綁定相應事件 for (var i = 0; i < Kodo.Events[guid][type].length; i++) { //循環執行那個方法數組便可 Kodo.Events[guid][type][i].call(dom, e); //正確的dom回調 } }, false); }
因爲方法過長,我就把講解的都寫在了代碼裏,這樣看的也會更方便一些。ui
代碼仍是不夠形象!咱們來看看log就能更清晰明白其中的奧祕。this
經過控制檯log出f.Events
發現正是咱們想要的結果,每一個dom
對應一個本身的evtObj
, 經過Kodo.Events[guid]
能夠獲得指定的evtObj
。而後便可取出本身相應的事件。
若是我繼續新增事件
能夠發現,我只針對於第一個li增長了事件。log出Evnets也就只有第一個Object有新增,而且會增長到對應的事件數組裏。
理解了這個後要解除事件綁定,那就很是簡單了。一樣根據guid查找到對應的方法數組,delete便可
off: function(type, selector) { if (arguments.length == 0) { //若是沒傳參數,清空全部事件 for (var i = 0; i < this.length; i++) { var id = this[i].guid; for (var j in Kodo.Events[id]) { delete Kodo.Events[id][j]; } } } else if (arguments.length == 1) { //指定一個參數,則清空對應type的事件 for (var i = 0; i < this.length; i++) { var id = this[i].guid; delete Kodo.Events[id][type]; } } }
一個沒有帶有事件委託的on、off就能夠這樣實現了。
那若是咱們要實現帶委託的怎麼辦呢?
咱們能夠用這一樣的思路實現,只是要多進行一個指定selector的存儲。
這個咱們就放在下一課最後講解。
star是尊重做者知識果實最好的回報 :)
github地址: https://github.com/MeCKodo/forchange/tree/master/lesson-9
可想實現一個本身的簡單jQuery庫?(九):http://segmentfault.com/a/1190000004028768