首页 > 网站 > WEB开发 > 正文

jQuery-1.9.1源码分析系列(十)事件系统——事件包装

2024-04-27 15:02:41
字体:
来源:转载
供稿:网友

  首先需要明白,浏览器的原生事件是只读的,限制了jQuery对他的操作。举个简单的例子就能明白为什么jQuery非要构造一个新的事件对象。

  在委托处理中,a节点委托b节点在a被click的时候执行fn函数。当事件冒泡到b节点,执行fn的时候上下文环境需要保证正确,是a节点执行了fn而非b节点。如何保证执行fn的上下文环境是a节点的:看源码红色部分

//执行ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ).apply( matched.elem, args );

  使用了apply将执行函数的上下文替换成了a节点(matched.elem)。还有一点args[0]即是事件对象event。又如何保证event是a节点的事件的?这就是event.currentTarget这个重要的属性的功能,所以在执行apply之前还做了一步操作

event.currentTarget = matched.elem;

  直接更改事件对象的currentTarget属性,这在浏览器本地事件是做不到的。所以才有了基于本地事件构造jQuery的事件对象。

 

  事件分两种:鼠标事件和键盘事件(不知道触摸事件何时能加进来)。看一下这两者的详细属性

  

  其中有些是浏览器自己的,非W3C标准的。jQuery将事件属性分为三块

  鼠标和键盘事件共同拥有的属性jQuery.event.PRops: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" ")

  键盘事件专有的属性jQuery.event.keyHooks.props: "char charCode key keyCode".split(" ")

  鼠标事件专有的属性jQuery.event.mouseHooks.props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" ")

  

a. 构造新的事件对象jQuery.event.fix(originalEvent)


  构造新的事件对象分三步完成

  第一步,使用到event = new jQuery.Event( originalEvent ),构造新事件对象(不明白new的作用的请点击这里),并在创建事件的时候加上isDefaultPrevented、originalEvent、type 、timeStamp和事件已经被修正过的标记(优化使用,避免不必要的处理)。jQuery.Event(src, props)的源码如下

jQuery.Event = function( src, props ) {    // Allow instantiation without the 'new' keyWord    if ( !(this instanceof jQuery.Event) ) {        return new jQuery.Event( src, props );    }    //src为事件对象    if ( src && src.type ) {        this.originalEvent = src;        this.type = src.type;        //事件冒泡的文档可能被标记为阻止默认事件发生;这个函数可以反应是否阻止的标志的正确值        this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false ||            src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse;    //src为事件类型    } else {        this.type = src;    }    //将明确提供的特征添加到事件对象上    if ( props ) {        jQuery.extend( this, props );    }    //创建一个时间戳如果传入的事件不只一个    this.timeStamp = src && src.timeStamp || jQuery.now();    //标记事件已经修正过    this[ jQuery.expando ] = true;};
View Code
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表