zoukankan      html  css  js  c++  java
  • 事件模块的演变(3)

    上一篇中的add有个问题,对同一类型事件添加多个hanlder时,IE6/7/8下会无序,如

    <div id="d1" style="200px;height:200px;background:gold;"></div>
    <script type="text/javascript">
    	var el = document.getElementById('d1');
    	function handler1(){alert('1');}
    	function handler2(){alert('2');}
    	function handler3(){alert('3');}
    	function handler4(){alert('4');}
    	function handler5(){alert('5');}
    	E.add(el, 'click', handler1);
    	E.add(el, 'click', handler2);
    	E.add(el, 'click', handler3);
    	E.add(el, 'click', handler4);
    	E.add(el, 'click', handler5);
    </script>
    

    IE9/Firefox/Safari/Chomre/Opera会依次输出1,2,3,4,5。但IE6/7/8中则不一定。为解决所有浏览器中多个事件handler有序执行,我们需要一个队列来管理所有的handler。

    这次,把所有的内部细节封装在一个匿名函数中,该函数执行完毕后返回如上一篇接口相同的方法。另外

    1. 把真正的事件handler挂在el上,即el.listeners,其为一个对象,每一个类型的事件为一个数组,如click为el.listeners["click"] = []
    2. 所有的handler存在在对于的数组中
    3. 删除一个hanlder,将从数组中将其删除
    E = function(){
    	function _isEmptyObj(obj){
    		for(var a in obj){
    			return false;
    		}
    		return true;
    	}
    	function _each(ary, callback){
    		for(var i=0,len=ary.length; i<len;){ 
    			callback(i, ary[i]) ? i=0 : i++;
    		}
    	}
    	function _remove(el, type){
    		var handler = el.listeners[type]['_handler_'];
    		el.removeEventListener ?
    			el.removeEventListener(type, handler, false) :
    			el.detachEvent('on'+type, handler);
    		delete el.listeners[type];
    		if(_isEmptyObj(el.listeners)){
    			delete el.listeners;
    		}
    	}
    	// 添加事件
    	function add(el, type, fn){
    		el.listeners = el.listeners || {};
    		var listeners = el.listeners[type] = el.listeners[type] || [];
    		listeners.push(fn);
    		if(!listeners['_handler_']){
    			listeners['_handler_'] = function(e){
    				var evt = e || window.event;
    				for(var i=0,fn; fn=listeners[i++];){
    					fn.call(el, evt);
    				}
    			}
    			el.addEventListener ?
    				el.addEventListener(type, listeners['_handler_'], false) :
    				el.attachEvent('on' + type,  listeners['_handler_']);
    		}
    	}
    	// 删除事件
    	function remove(el, type, fn){
    		if(!el.listeners) return;
    		var listeners = el.listeners && el.listeners[type];
    		if(listeners) {
    			_each(listeners, function(i, f){
    				if(f==fn){
    					return listeners.splice(i, 1);
    				}
    			});
    			if(listeners.length == 0){
    				_remove(el,type);
    			}
    		}
    	}
    	//主动触发事件
    	function dispatch(el ,type){
    		try{
    			if(el.dispatchEvent){
    				var evt = document.createEvent('Event');
    				evt.initEvent(type,true,true);
    				el.dispatchEvent(evt);
    			}else if(el.fireEvent){
    				el.fireEvent('on'+type);
    			}
    		}catch(e){};
    	}	
    	return {
    		add: add,
    		remove: remove,
    		dispatch: dispatch
    	};
    }();
    

    相关:

    仅IE6/7/8下同一个类型事件的多个handler执行无序 

  • 相关阅读:
    Android ANR 知多少
    电源管理
    功耗分析
    手机功耗测试
    Battery Historian
    Android 电量优化
    Android手机功耗
    功耗 Log 抓取要求规范
    Android 手机无法进入系统解决方案
    定屏死机问题操作指南
  • 原文地址:https://www.cnblogs.com/snandy/p/2009530.html
Copyright © 2011-2022 走看看