js中邦定事件与解绑支持匿名函数
2014-03-16 22:06
369 查看
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>
和一个朋友讨论了一下,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中邦定事件与解绑支持匿名函数
- js中邦定事件与解绑支持匿名函数
- js事件绑定--支持匿名函数解除绑定
- Js事件监听封装(支持匿名函数)
- JavaScript的事件绑定(方便不支持js的时候)
- 封装了一个支持匿名函数的Javascript事件监听器
- JS判断浏览器是否支持触屏事件
- 一个通用的事件监听函数,能支持匿名函数的使用
- js动态绑定与解绑事件示例
- 封装了一个支持匿名函数的Javascript事件监听器
- js 判断对touch事件支持
- SpreadJS 在 Angular2 中支持哪些事件?
- js鼠标事件大全件 事件 浏览器支持 描述
- SpreadJS 在 Angular2 中支持哪些事件?
- js模拟一个回车事件(ie下支持)
- jquery textlimit.js显示TEXTAREA中剩余字符(不支持光标位置改变时触发事件)
- ireport超链接支持js事件简单实现 兼容火狐谷歌IE等浏览器
- JS添加事件和解绑事件:addEventListener()与removeEventListener()
- 手机轮播组件—支持事件回调和队列(原生js)
- js 添加和移除onclick事件(通过匿名函数实现)及jquery 移除事件