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

    上一篇正式推出了我的事件模块event-v0.1,已经搭起了它的初始框架。或许有人要说,与众多JS库或框架相比,它还没有解决事件对象的兼容性问题。是的,我故意将此放到后续补充。因为事件对象的兼容性问题太多了,太繁琐了。

     

    这篇我将引入一个私有的_fixEvent函数,add中将调用该函数。_fixEvent将修复(或称包装)原生事件对象,返回一个标准的统一接口的事件对象。如下

    function _fixEvent( evt, el ) {
    	var props = "altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),
    		len   = props.length;
    	function now() {return (new Date).getTime();}
    	function returnFalse() {return false;}
    	function returnTrue() {return true;}
    	function Event( src ) {
    		this.originalEvent = src;
    		this.type = src.type;
    		this.timeStamp = now();
    	}
    	Event.prototype = {
    		preventDefault: function() {
    			this.isDefaultPrevented = returnTrue;
    			var e = this.originalEvent;
    			if( e.preventDefault ) {
    				e.preventDefault();
    			}
    			e.returnValue = false;
    		},
    		stopPropagation: function() {
    			this.isPropagationStopped = returnTrue;
    			var e = this.originalEvent;
    			if( e.stopPropagation ) {
    				e.stopPropagation();
    			}		
    			e.cancelBubble = true;
    		},
    		stopImmediatePropagation: function() {
    			this.isImmediatePropagationStopped = returnTrue;
    			this.stopPropagation();
    		},
    		isDefaultPrevented: returnFalse,
    		isPropagationStopped: returnFalse,
    		isImmediatePropagationStopped: returnFalse
    	};
    
    	var originalEvent = evt;
    	evt = new Event( originalEvent );
    	
    	for(var i = len, prop; i;) {
    		prop = props[ --i ];
    		evt[ prop ] = originalEvent[ prop ];
    	}
    	if(!evt.target) {
    		evt.target = evt.srcElement || document;
    	}
    	if( evt.target.nodeType === 3 ) {
    		evt.target = evt.target.parentNode;
    	}
    	if( !evt.relatedTarget && evt.fromElement ) {
    		evt.relatedTarget = evt.fromElement === evt.target ? evt.toElement : evt.fromElement;
    	}
    	if( evt.pageX == null && evt.clientX != null ) {
    		var doc = document.documentElement, body = document.body;
    		evt.pageX = evt.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
    		evt.pageY = evt.clientY + (doc && doc.scrollTop  || body && body.scrollTop  || 0) - (doc && doc.clientTop  || body && body.clientTop  || 0);
    	}
    	if( !evt.which && ((evt.charCode || evt.charCode === 0) ? evt.charCode : evt.keyCode) ) {
    		evt.which = evt.charCode || evt.keyCode;
    	}
    	if( !evt.metaKey && evt.ctrlKey ) {
    		evt.metaKey = evt.ctrlKey;
    	}
    	if( !evt.which && evt.button !== undefined ) {
    		evt.which = (evt.button & 1 ? 1 : ( evt.button & 2 ? 3 : ( evt.button & 4 ? 2 : 0 ) ));
    	}		
    	if(!evt.currentTarget) evt.currentTarget = el;
    
    	return evt;
    }	
    

    好了,现在你要

    1,阻止事件默认行为,统一使用e.preventDefault()

    2,停止冒泡,统一使用e. stopPropagation()

    3,获取事件源,统一使用e.target

    ...


    更多的差异性,不在这一一列举了。请参考我在google doc上整理的文档:各浏览器中事件对象差异性列表。呃,不能FQ的同学抱歉了。以下是我的事件模块最终版功能

    1,最基本的添加、删除监听函数的事 

    function handle(){
    	//todo
    }
    E.add(document,'click',handle);
    E.remove(document,'click',handle);
    

    2,为同一个元素添加多个handle时,执行有序。所有浏览器中依次弹出1,2,3,4,5

    function handle1(){alert(1);}
    function handle2(){alert(2);}
    function handle3(){alert(3);}
    function handle4(){alert(4);}
    function handle5(){alert(5);}
    E.add(document,'click',handle1);
    E.add(document,'click',handle2);
    E.add(document,'click',handle3);
    E.add(document,'click',handle4);
    E.add(document,'click',handle5);
    

    3,添加仅执行一次的handler

    function handler(){
    	alert(1);
    }
    E.add(document,'click',handler,true);
    

    4,删除元素指定类型的所有handler

    function handle1(){
    	alert(1);
    }
    function handle2(){
    	alert(2);
    }
    E.add(document,'click',handle1);
    E.add(document,'click',handle2);
    
    E.remove(document,'click'); //删除了handle1和handle2
    

    5,删除附加元素上的所有handler

    function handle1(){
    	alert(1);
    }
    function handle2(){
    	alert(2);
    }
    E.add(document,'click',handle1);
    E.add(document,'mouseover',handle2);
    
    E.remove(document);
    

    6,主动触发事件。如模拟用户点击

    function handle(){
    	alert(1);
    }
    E.add(document,'click',handle);
    E.dispatch(document,'click'); 
    

    7,解决事件对象的兼容性问题,如阻止默认行为,停止冒泡等(支持DOM2/3 events)


    event-v0.2

  • 相关阅读:
    c# WinForm 定时执行某个后台操作 如把B文件夹下的文件Copy到A文件夹下
    c# 创建指定大小的空字符填充的文本文件 在指定位置读写相关内容
    c# DirectShow 通过IAMVideoProcAmp的Set方法 来设置视频图像的Brightness 调整亮度
    [转]灰度图像的腐蚀算法和细化算法(C#代码)
    利用fleximage实现图片上传
    利用acts_as_ferret实现全文检索
    纯CSS无hacks的跨游览器多列布局
    IE私有CSS样式属性一览
    利用thinking sphinx实现全文检索
    搭建rails运行环境
  • 原文地址:https://www.cnblogs.com/snandy/p/2010179.html
Copyright © 2011-2022 走看看