博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
js中邦定事件与解绑支持匿名函数
阅读量:4557 次
发布时间:2019-06-08

本文共 2509 字,大约阅读时间需要 8 分钟。

js中邦定事件与解绑支持匿名函数

和一个朋友讨论了一下,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>

转载于:https://www.cnblogs.com/baiduligang/p/4247651.html

你可能感兴趣的文章
两只小熊队高级软件工程第七次作业敏捷冲刺2
查看>>
[原创]如何编写多个阻塞队列连接下的多生产者多消费者的Python程序
查看>>
如何提高数据迁移和复制的速度
查看>>
.9图片
查看>>
android打开各种文件Intent
查看>>
[转][C#]单例模式之懒加载
查看>>
实验吧之【后台登录,加了料的报错注入,认真一点】(报错注入)
查看>>
MySQL无法存储Emoji表情问题
查看>>
HDFS集中式的缓存管理原理与代码剖析
查看>>
POJ1019 Number Sequence
查看>>
第十七章-异步IO
查看>>
Linux就该这么学
查看>>
out传值
查看>>
CentOS6.8【环境配置篇】
查看>>
线程同步的方式
查看>>
Mongodb 安装
查看>>
WPF窗口贴边隐藏(类似QQ)
查看>>
VS2008无法切换到视图设计器
查看>>
爱情故事:追忆似水流年 回味永恒的爱恋
查看>>
android mvn android:deploy签名问题
查看>>