首页 > 代码库 > 事件绑定(终极版)

事件绑定(终极版)

1.问题所在

现代绑定中W3C使用的是:addEventListener和removeEventListener。IE使用的是attachEvent和detachEvent。我们知道IE的这两个问题多多,并且伴随内存泄漏。所以,解决这些问题非常有必要。

那么我们希望解决非IE浏览器事件绑定哪些问题呢?

1.支持同一元素的同一事件句柄可以绑定多个监听函数;

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 = http://www.mamicode.com/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 }

事件绑定(终极版)