关于事件部分,我思考了好久,也参考了许多,到底如何能用一个很简单的方法实现如出一辙的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