• 添加、移除事件及相关处理函数各方法


    给dom元素绑定事件监听,刚入门的javascript编程人员都可以办到,比如obj.onclick = fn

    obj.onclick = fn1;
    obj.onclick = fn2;
    ...
    

    可如果这么做,fn2会把fn1覆盖,也就是说在单击obj时只会执行fn2中的代码片段,fn1则会被忽略,很显然这样不能满足我们的需求。

    在考虑到这个问题的时候,JS已经为我们准备了像attachEvnet、addEventListener这样的方法来满足我们的需求,利用对能力检测还是可以轻松的实现一个兼容的方法:

    function bindEvent(elem,type,fn){
      if(elem.addEventListener){
        elem.addEventListener(type,fn,false);
      }else{
        elem.attachEvent("on"+type,fn);
      }
    bindEvent(obj,"click",fn1);
    bindEvent(obj,"click",fn2);

    这样目的就达到了,当单击obj时,依次执行fn1、fn2。

    解决了这个问题后,细心的淫们会发现在用attachEvent添加事件处理函数,执行的function中this执行是有问题的,始终指向window,又不是一个不小的麻烦。

    那么有没有办法,来解决这个棘手的问题呢,答案是肯定的,这正是我写这篇文章的意义所在,废话!

    其实只需对bindEvent稍作加工即可,如下:

    function bindEvent(elem,type,fn){
        if(elem.addEventListener){
    		elem.addEventListener(type,fn,false);
        }else{
            elem.attachEvent("on"+type,function(){
                fn.apply(elem,arguments);
            });
        }
    }
    bindEvent(obj,"mouseover",function(){alert(this)})
    

    理论上,这样的解决方案近乎完美了,但是还有一个问题亟待解决,因为在attachEvent中使用了匿名函数来执行fn,导致在无法使用 detachEvent来删除绑定的某个代码片段,也许obj["on"+type] = null可以解决,清空绑定的代码片段,这很粗暴邪恶,同时也违背我们的业务需求。

    我想要从根本上解决这些问题,就一定抛弃attachEvent这个方法,事实上我也是这样做的,如下:

    (function(win,doc){
    	var Event = {};
    	
    	Event.add = function(elem,type,fn){
    		if(doc.addEventListener){
    			elem.addEventListener(type,fn,false);
    		}else{
    			var typeRef = "_" + type;
    	        if(!elem[typeRef]){
    	            elem[typeRef] = [];
    	        }
    	        var len = elem[typeRef].length;
    	        while(len-->0){
    	        	if(elem[typeRef][len] === fn)return;
    	        }
    	        elem[typeRef].push(fn);
    	        elem["on"+type] = function(){
    	        	len = this[typeRef].length;
    	        	this[typeRef].reverse();
    	        	while(len-->0){
    	        		this[typeRef][len].apply(this,arguments);
    	        	}
    	        	this[typeRef].reverse();
    	        }
    		}
    	};
    	Event.remove = function(elem,type,fn){
    		if(doc.addEventListener){
    			elem.removeEventListener(type,fn,false);
    		}else{
    			var typeRef = "_" + type;
    			if(elem[typeRef]){
    				var len = elem[typeRef].length;
    				while(len-->0){
    					if(elem[typeRef][len] === fn){
    						elem[typeRef].splice(len,1);
                        	break;
    					};
    				}
            	}
    		}
    	};
    	Event.getEve = function(e){
    		return e || win.event;
    	};
    	Event.target = function(e){
    		e = this.getEve(e);
    		return e.target || e.srcElement;
    	};
    	Event.preventDefault = function(e){ //阻止默认事件
    		e = this.getEve(e);
    		e.preventDefault ? e.preventDefault() : e.returnValue = false;
    	};
    	Event.stopPropagation = function(e){ //阻止冒泡
    		e = this.getEve(e);
    		e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true;
    	};
    	win.Event = Event;
    })(window,document);
    

      

      

  • 相关阅读:
    IT English Collection(16) of Message
    TO DO NOW——送给奋斗着的程序“猿”们
    题目:[NOIP1999]拦截导弹(最长非递增子序列DP) O(n^2)和O(n*log(n))的两种做法
    hdu 1695 GCD
    paip.提升用户体验---c++ qt 取消gcc编译的警告信息.txt
    hive优化要点总结
    HDU 4099 Revenge of Fibonacci (数学+字典数)
    JSP小实例--计算器
    关于产品的一些思考——百度之百度百科
    正则表达式JSP实例
  • 原文地址:https://www.cnblogs.com/pangzai/p/4809424.html
Copyright © 2020-2023  润新知