首先需要明白,浏览器的原生事件是只读的,限制了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的事件对象。

 

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

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

  其中有些是浏览器自己的,非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-1.9.1源码分析系列(十) 事件系统——事件包装
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

相关文章:

  • 2021-07-21
  • 2022-03-02
  • 2021-10-14
  • 2021-10-19
  • 2021-07-31
  • 2021-12-06
  • 2021-11-26
  • 2021-06-18
猜你喜欢
  • 2021-10-11
  • 2021-06-05
  • 2021-06-29
  • 2021-09-08
  • 2021-12-08
  • 2021-08-12
  • 2021-12-19
相关资源
相似解决方案