zoukankan      html  css  js  c++  java
  • 添加、移除事件及相关处理函数各方法

    给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);
    

      

      

  • 相关阅读:
    RUST实践.md
    redis.md
    opencvrust.md
    aws rds can't connect to mysql server on 'xx'
    Foundation ActionScript 3.0 With Flash CS3 And Flex
    Foundation Flash Applications for Mobile Devices
    Flash Mobile Developing Android and iOS Applications
    Flash Game Development by Example
    Actionscript 3.0 迁移指南
    在SWT中非UI线程控制界面
  • 原文地址:https://www.cnblogs.com/pangzai/p/4809424.html
Copyright © 2011-2022 走看看