和一個朋友討論了一下,DOM2綁定方式都是有名的函數,匿名的處理起來有些麻煩,而且即使是有名的函數,在IE低版本的瀏覽器也是解除不掉的,this指向需要修改,着實費了一番功夫,這個是兼容ie低版本的,可能代碼不是最優的,希望朋友們提出優化意見或者需要改進的地方,話不多說,上菜:
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<title>無標題文檔</title>
</head>
<script>
function addEvent(obj,ev,fn){
var fnName = getFuncName(fn) || Math.random()+''+Math.random(); //如果函數名不存在的話 則取兩次隨機數(避免重復)作為函數存入的key值
var func = function(){ //將函數專為匿名函數並改變this指向 低版本ie下的必然操作 標准下如此操作沒有副作用
fn.apply(obj,arguments);
}
obj.funByEv = obj.funByEv || {}
obj.funByEv[ev] = obj.funByEv[ev] || [];
var _json = {}; //新建的json
_json[fnName] = func; //key:傳進來的函數的名字 value:傳進來的函數轉變的匿名函數
obj.funByEv[ev].push( _json ); //將json push到數組里
if(obj.addEventListener){
obj.addEventListener(ev,func,false);
}else{
obj.attachEvent('on'+ev,func);
}
}
function removeEvent(obj,ev,fn){
var fnName = getFuncName(fn); //函數名 getFuncName()內部處理 如果傳匿名函數或沒有傳函數 則返回null 否則返回函數名
var iBtn = false; //用來結束數組循環查找的開關
var len = obj.funByEv[ev].length;
if(fn&&fnName){ //如果傳進來數組 且數組有名字 則走if語句
for(var i=0;i<len;i++){ //循環 解除綁定對象的屬性下對應事件的數組
for(var j in obj.funByEv[ev][i] ){ //在數組每項中 用json的key與解除的函數匹配
if (j == fnName){ //匹配成功 則刪除對應的函數
obj.removeEventListener ? obj.removeEventListener(ev,obj.funByEv[ev][i][fnName],false) : obj.dettachEvent('on'+ev,obj.funByEv[ev][i][fnName]);
iBtn = true; //刪除后 則可以結束循環
}
}
if(iBtn)break; //非常重要 同一個函數綁定給同個對象多次,這里認為解除哪個都一樣(也許是有區別的,) 所以解除掉一個后,就退出數組循環
}
}else{ //如果沒有傳函數,或者傳入的是匿名函數 對不起 干掉所有綁定的
for(var i=0;i<len;i++){ //同if操作.只是不用去匹配 json的key和需要解除的函數的名字
for(var k in obj.funByEv[ev][i]){ //原因? 干掉每一個 當然不用去匹配了
obj.removeEventListener ? obj.removeEventListener(ev,obj.funByEv[ev][i][k],false) : obj.detachEvent('on'+ev,obj.funByEv[ev][i][k]);
}
}
}
}
function getFuncName(fn){
if(!fn)return null; //如果沒有傳函數名,則返回空
var reg = /\bfunction\s+([^(]+)/; //正則匹配函數名
var result = fn.toString().match(reg); //通過正則表達式在函數轉的字符串中得到數組
return result ? result[1] : null; //取出第一個子項的結果 即為函數名 若沒有找到
}
</script>
<script>
addEvent(window,'load',onLoad);
function onLoad(){
var oDiv = document.getElementsByTagName('div')[0];
addEvent(oDiv,'click',function(){alert(this)});
addEvent(oDiv,'click',_a);
addEvent(oDiv,'click',_b);
addEvent(oDiv,'click',_b);
addEvent(oDiv,'mouseover',function(){this.style.background='black'});
removeEvent(oDiv,'mouseover');
}
function _a(){
alert(1);
}
function _b(){
alert(2);
}
function _c(){
alert(3);
}
</Script>
<body>
<div>1111111111</div>
</body>
</html>
