zoukankan      html  css  js  c++  java
  • 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 = /functions+([^(]+)/;    //正则匹配函数名
    	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>
  • 相关阅读:
    PyQt作品 – PingTester – 多点Ping测试工具
    关于和技术人员交流的一二三
    Pyjamas Python Javascript Compiler, Desktop Widget Set and RIA Web Framework
    Hybrid Qt applications with PySide and Django
    pyjamas build AJAX apps in Python (like Google did for Java)
    PyQt 维基百科,自由的百科全书
    InfoQ:请问为什么仍要选择Java来处理后端的工作?
    Eric+PyQt打造完美的Python集成开发环境
    python select module select method introduce
    GUI Programming with Python: QT Edition
  • 原文地址:https://www.cnblogs.com/icss/p/3222414.html
Copyright © 2011-2022 走看看