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/icss/p/3222414.html
js中邦定事件与解绑支持匿名函数相关推荐
- JS中window.onload事件详解
window.onload出现的原因? 我们都知道页面的代码顺序是从上往下进行加载,很多时候我们要对页面中的某一个模块进行操作,这时候我们常常使用javascript代码来进行操作.为了能够保证操作 ...
- js中鼠标滚轮事件详解
<body style="height:2000px"><script type="text/javascript">var scrol ...
- jquery事件绑定解绑机制源码分析
引子 为什么Jquery能实现不传回调函数也能解绑事件?如下: $("p").on("click",function(){alert("The par ...
- JQuery事件绑定解绑方法小结
常用的方法 绑定:bind().delegate().on() 解绑:unbind().undelegate().off() 此外还有live() 不过JQuery1.9及其以上版本删除了此方法 推荐 ...
- JS中的event 对象详解
JS中的event 对象详解 JS的event对象 Event属性和方法: 1. type:事件的类型,如onlick中的click: 2. srcElement/target:事件源,就是发生事件的 ...
- WPF中的鼠标事件详解
WPF中的鼠标事件详解 Uielement和ContentElement都定义了十个以Mouse开头的事件,8个以PreviewMouse开头的事件,MouseMove,PreviewMouseMov ...
- JS中的click事件无反应
JS中的click事件无反应 今天在一个js文件中写了一个click函数,结果在页面中点击后死活没有反应,各种检查之后代码也没问题,就是无法触发click函数.各种百度之后终于找到了问题所在:在点击的 ...
- JS中常用的事件操作
JS中常用的事件操作 前言 一.点击事件(导航栏内容切换功能) 二.移入移出事件(导航栏菜单下拉功能) 三.失去焦点事件(表单检验功能) 四.鼠标事件(鼠标跟随功能) 五.键盘事件(打飞机案例) 总结 ...
- js中indexOf的用法详解
js中indexOf的用法详解 String.IndexOf 方法 (Char, [startIndex], [count]) 报告指定字符在此实例中的第一个匹配项的索引.搜索从指定字符位置开始,并检 ...
- js中的onclick事件在ul获取li时点击两次才会执行的原因
js中的onclick事件在ul获取li时点击两次才会执行的原因 下面的代码中 只有onclick第二次才会执行函数内部的代码 代码实例如下: <!DOCTYPE html> <ht ...
最新文章
- 数论基础--矩阵快速幂 及其例题
- http://m.blog.csdn.net/article/details?id=2630620
- B.Sport Mafia
- (0055)iOS开发之dealloc认识
- 【vue】ios中从详情页中返回到列表页出现空白的问题
- Java IO: 序列化与ObjectInputStream、ObjectOutputStream
- Jenkins 入门系列--jenkins 介绍
- 摩尔斯电码转换python编码_Morse Code 用Python做个摩斯密码转换器
- TensorFlow2.0:梯度计算
- 自由软件之父回归 FSF,遭 1933 人、21 家组织联名抵制!
- 001 lambda的分析
- solidworks迈迪设计宝_机械入门|那些看起来很牛X的机械结构,是如何设计的?...
- rtthread qspi w25q256
- java运行环境安装步骤_安装JAVA运行环境步骤
- 时域采样与频域采样实验【matlab】
- 面包板电源线怎么接_电路实验中,直接用面包板连接线将电源短路会产生什么问题?...
- LeetCode知识点总结 - 1179
- Python 修改AD账号密码(一)- 启用域控LDAPS
- 心灵成长的六个定律 (3) - By 武志红
- 汇通达港交所上市:市值超240亿港元 阿里与顺为是股东