一直觉得浏览器默认的事件管理机制不是很灵活,参照DOM3的EventListenerList机制简单做了一下扩展
<script>
/* global EventTarget*/
'use strict';
EventTarget.prototype.addEventListenerBase = EventTarget.prototype.addEventListener;
EventTarget.prototype.addEventListener = function(type, listener) {
if (!(listener instanceof Function)) {
window.console.error('[listener] is not a function, from addEventListener(type, listener)');
window.console.log(listener);
return;
}
if (!this.EventList) this.EventList = {};
if (!this.EventList[type]) this.EventList[type] = {index: 0};
var result = -1;
var list = this.EventList[type];
for (var i = list.index - 1; i > -1; i--) {
if (list[i] === listener) {
result = i;
break;
}
}
if (result === -1) {
result = list.index;
list[list.index++] = listener;
}
this.addEventListenerBase.apply(this, arguments);
return result;
};
EventTarget.prototype.removeEventListenerBase = EventTarget.prototype.removeEventListener;
EventTarget.prototype.removeEventListener = function(type, listener) {
if (arguments.length === 0) {
if (!this.EventList) this.EventList = {};
for (var i in this.EventList) {
if (this.EventList.hasOwnProperty(i)) {
this.removeEventListener(i);
}
}
} else if (arguments.length === 1) {
if (this.EventList && this.EventList[type] && this.EventList[type].index) {
for (var i = this.EventList[type].index - 1; i > -1; i--) {
this.removeEventListener(type, i);
}
}
} else if (arguments.length > 1) {
if (!(listener instanceof Function) && !String(listener).replace(/\D/g, '')) {
window.console.error('[listener] is not a function or number, from removeEventListener(type, listener)');
window.console.log(listener);
return;
}
if (!this.EventList) this.EventList = {};
if (!this.EventList[type]) return;
var list = this.EventList[type];
for (var i = list.index - 1; i > -1; i--) {
if (!list[i]) continue;
if (listener === list[i] || String(listener) === String(i)) {
this.removeEventListenerBase(type, list[i]);
list[i] = undefined;
}
}
}
};
function logg(str) {
out.innerHTML += str + ' '
}
</script>
<button id="tt">click test</button> <br/><br/>
<button onclick="tt1.idx=tt.addEventListener('click', function() {logg('click 1');});">add1</button>
<button onclick="tt2.idx=tt.addEventListener('click', function() {logg('click 2');});">add2</button>
<button id="tt1" onclick="tt.removeEventListener('click', this.idx)">rm1</button>
<button id="tt2" onclick="tt.removeEventListener('click', this.idx)">rm2</button>
<button onclick="tt.removeEventListener('click')">rm_all</button>
<button onclick="tt.removeEventListener()">clear_all</button>
<br/>
<br/>
<div id="out"></div>