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

js中邦定事件与解绑支持匿名函数的更多相关文章

  1. js中鼠标滚轮事件详解

    js中鼠标滚轮事件详解   (以下内容部分内容参考了http://adomas.org/javascript-mouse-wheel/ ) 之前js 仿Photoshop鼠标滚轮控制输入框取值中已使用 ...

  2. JS中的event 对象详解

    JS中的event 对象详解   JS的event对象 Event属性和方法:1. type:事件的类型,如onlick中的click:2. srcElement/target:事件源,就是发生事件的 ...

  3. 从零开始学 Web 之 jQuery(六)为元素绑定多个相同事件,解绑事件

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  4. 【转载】C# 中的委托和事件(详解:简单易懂的讲解)

    本文转载自http://www.cnblogs.com/SkySoot/archive/2012/04/05/2433639.html C# 中的委托和事件(详解) C# 中的委托和事件 委托和事件在 ...

  5. JS中的计时器事件

    JS可以实现很多java代码不易完成的功能.这里学习一些js中的计时器事件. JavaScript 一个设定的时间间隔之后来执行代码,称之为计时事件. 主要通过两个方法来实现: 1.setInterv ...

  6. js中中括号,大括号使用详解

    js中中括号,大括号使用详解 一.总结 一句话总结:{ } 是一个对象,[ ] 是一个数组 1.js大括号{}表示什么意思? 对象 { } 大括号,表示定义一个对象,大部分情况下要有成对的属性和值,或 ...

  7. js中的计时器事件`setTimeout()` 和 `setInterval()`

    js中的计时器事件 在js中,通常会有一些事件,我们需要让它 间隔一段时间之后再发生,或者 每隔一段时间 发生一次,那就需要用到我们js中的计时事件 计时事件主要有两种: setTimeout() - ...

  8. react第五单元(事件系统-原生事件-react中的合成事件-详解事件的冒泡和捕获机制)

    第五单元(事件系统-原生事件-react中的合成事件-详解事件的冒泡和捕获机制) 课程目标 深入理解和掌握事件的冒泡及捕获机制 理解react中的合成事件的本质 在react组件中合理的使用原生事件 ...

  9. 5月23日笔记-js绑定事件、解绑事件、复合事件

    each() $("p").each(function(i,ele){ //alert(ele.innerHTML); alert($("p:eq("+i+&q ...

随机推荐

  1. JavaScript对象(一)——Function对象

    写在最前面: 对象只是带有属性和方法的特殊数据类型(js的7种数据类型:字符串,数字,布尔,数组,对象,null,undefined). JavaScript是面向对象的语言,但是JavaScript ...

  2. js 事件小结

    1,事件对象   e || window.event //ie   2, 取鼠标点击坐标 带有滚动条的   var top = document.documentElement.scrollTop | ...

  3. pymssql文档

    原文地址 http://pymssql.org/en/latest/ref/_mssql.html _mssql module reference pymssql模块类,方法和属性的完整文档. Com ...

  4. struts2注解驱动 零配置

    一.配置web.xml<filter><filter-name>struts2</filter-name><filter-class>org.apach ...

  5. CentOS6.4卸载自带的OpenJDK并安装jdk1.6.21

    #进入系统的terminal,查看当前的jdk版本: shell>java -version #查看安装包 shell>rpm -qa|grep java #将上条命令查出来的结果卸载掉, ...

  6. C#基础之------进制转换

    /************************ File:控制台进制类型转换实现 Time:2014年8月12日 Author:小X ****************************/ 代 ...

  7. linux 添加自定义环境变量

    1. vi /etc/profile ,在文件末尾加上要定义的环境变量,语法如下: export 变量名=变量值

  8. Java注释模板设置详解

    设置注释模板的入口: Window->Preference->Java->Code Style->Code Template 然后展开Comments节点就是所有需设置注释的元 ...

  9. C# Nullable可空类型

    一个Nullable类型就是基本类型加上一个"是否为null指示器"的合成类型.对于一个类型,如果既可以给他分配一个值,也可以给它分配null引用,我们就说这个类型是可空的. 可空 ...

  10. C# Process类_进程管理器Demo

    Process用于管理计算机的进程,下面给出一个C#进程管理器的DEMO. namespace ProcessManager { public partial class Form1 : Form { ...