事件绑定(终极版)

内容提纲:

1.问题所在

2.设置代码

发文不易,转载注明出处!

 

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 = 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 }

 

你可能感兴趣的:(事件)