1、自定义事件(用户手动trigger的一般都是自定义事件)

trigger: function( event, data, elem, onlyHandlers ) {

  var i, cur, tmp, bubbleType, ontype, handle, special,

    // 如果没有传入elem(绑定到那个DOM元素上的事件),则默认为document
    eventPath = [ elem || document ],

    // core_hasOwn是hasOwnProperty的替代,检测event上是否有type属性,如果有就将其赋值给type,否则说明event就是type
    type = core_hasOwn.call( event, "type" ) ? event.type : event,

    // 事件的命名空间处理
    namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];

    cur = tmp = elem = elem || document;

  // 如果元素时文本节点或者是注释则直接返回
  if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
    return;
  }

  // 排除替代事件??
  if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
    return;
  } 

  // 如果type中有.号,

  if ( type.indexOf(".") >= 0 ) {
    // 得到自定事件的所有命名空间
    namespaces = type.split(".");

    // 第一个是自定义事件的类型
    type = namespaces.shift();

    // 
    namespaces.sort();
  }

  // 如果type中没有冒号,则为type加上“on”
  ontype = type.indexOf(":") < 0 && "on" + type;

  // 看看有没有jQuery封装后的event对象的标记,如果没有则进行一下改造
  event = event[ jQuery.expando ] ?
    event :
    new jQuery.Event( type, typeof event === "object" && event );

  // 为event对象添加一些额外的属性
  event.isTrigger = onlyHandlers ? 2 : 3;
  event.namespace = namespaces.join(".");
  event.namespace_re = event.namespace ?
    new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
    null;

  // 重置event的result属性
  event.result = undefined;

  // 如果event没有target属性,则将elem赋值给它
  if ( !event.target ) {
    event.target = elem;
  }

  // 将传入的data放到数组中,并将event放到数组的第二个元素位置
  data = data == null ?
    [ event ] :
    jQuery.makeArray( data, [ event ] );

  // 看看是不是特殊事件,如果是,用特殊事件的处理方式,并在返回false时返回。
  special = jQuery.event.special[ type ] || {};
  if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
    return;
  }

  // 如果不是onlyHandlers 并且特殊事件不需要冒泡,并且不是window
  if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {

    // 如果有替代事件类型,则使用替代事件类型

    bubbleType = special.delegateType || type;

    // 如果不是foucusin和foucusout事件
    if ( !rfocusMorph.test( bubbleType + type ) ) {

      // 则将当前指定为该元素的父元素
      cur = cur.parentNode;
    }

    // 遍历自身及其所有祖先元素,因为自动义事件不会向上冒泡
    for ( ; cur; cur = cur.parentNode ) {

      // 将他们推入eventpath中。
      eventPath.push( cur );
      tmp = cur;
    }

    // 如果最后一个cur是document,则事件触发到window对象上,将window推入队列
    if ( tmp === (elem.ownerDocument || document) ) {
      eventPath.push( tmp.defaultView || tmp.parentWindow || window );
    }
  }

  // 触发该元素上的所有事件处理函数
  i = 0;
  while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {

    event.type = i > 1 ?
      bubbleType :
      special.bindType || type;

    // 拿到对应的event和handle
    handle = ( data_priv.get( cur, "events" ) || {} )[ event.type ] && data_priv.get( cur, "handle" );
    if ( handle ) {

      // 如果有handle就触发
      handle.apply( cur, data );
    }

    // 拿到原始的事件类型
    handle = ontype && cur[ ontype ];

    // 看是否需要阻止默认事件
    if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) {
      event.preventDefault();
    }
  }  

  // 事件类型可能变了,重新赋值
  event.type = type;

  // 如果不需要阻止默认事件
  if ( !onlyHandlers && !event.isDefaultPrevented() ) {

    if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
      jQuery.acceptData( elem ) ) {

      如果存在原始类型,并且存在事件处理函数,并且不是window
      if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) ) {

        // 元素上的事件赋值给临时变量
        tmp = elem[ ontype ];

        // 清空该元素上的原始事件

        if ( tmp ) {
          elem[ ontype ] = null;
        }

        // 防止再次触发
        jQuery.event.triggered = type;

        // 触发事件处理程序
        elem[ type ]();

        // 清除标记防止再次触发的标记
        jQuery.event.triggered = undefined;

        if ( tmp ) {

          // 再把原始事件写回来
          elem[ ontype ] = tmp;
        }
      }
    }
  }

  // 返回最后一个事件处理程序的返回值

  return event.result;
},

jQuery事件处理(七)的更多相关文章

  1. [DOM Event Learning] Section 3 jQuery事件处理基础 on(), off()和one()方法使用

    [DOM Event Learning] Section 3 jQuery事件处理基础 on(),off()和one()方法使用   jQuery提供了简单的方法来向选择器(对应页面上的元素)绑定事件 ...

  2. jQuery事件处理了解一下

    >>> JQuery 事件处理 一.事件绑定方式 1.事件绑定的快捷方式: 缺点:绑定的事件,无法取消 $("button:eq(0)").dblclick(fu ...

  3. jQuery事件处理(四)

    看了几天,决定整理一下jQuery事件处理的整体设计思路 1.通过add方法给选中的元素注册事件处理程序(通过缓存系统将事件储存到cache,而不是绑定到元素上) a.在存储之前,会为事件处理程序增加 ...

  4. Unit02: jQuery事件处理 、 jQuery动画

    Unit02: jQuery事件处理 . jQuery动画 jQuery实现购物车案例 <!DOCTYPE html> <html> <head> <titl ...

  5. JQuery事件处理的注意事项

    1.jQuery 名称冲突 jQuery 使用 $ 符号作为 jQuery 的简介方式. 某些其他 JavaScript 库中的函数(比如 Prototype)同样使用 $ 符号. jQuery 使用 ...

  6. 从零开始学 Web 之 jQuery(七)事件冒泡,事件参数对象,链式编程原理

    大家好,这里是「 从零开始学 Web 系列教程 」,并在下列地址同步更新...... github:https://github.com/Daotin/Web 微信公众号:Web前端之巅 博客园:ht ...

  7. 02-老马jQuery教程-jQuery事件处理

    1. 绑定简单事件 在DOM中DOM0级绑定事件的方式是直接给事件属性赋值,但是这样有个缺点就是每次指定的事件处理程序会把之前的覆盖掉. jQuery简单绑定事件的方式,可以让我绑定多个事件处理程序跟 ...

  8. jQuery事件处理(六)

    1.通过一步步调试的的方法观察了一下存放到cache中的事件及其处理程序的数据格式: { events : { // 根据事件类型存放添加到该元素上的所有事件,下面以click为例 click : [ ...

  9. jQuery事件处理(五)

    对原生js不熟悉看jQuery会困难很多.后续需要更多的关注下原生js jQuery封装之后的事件触发,其中一个分支(处理普通事件)是通过:elem.addEventListener( type, e ...

随机推荐

  1. EF5+MVC4系列(5) 删除的方法 1:系统推荐的先查询后remove删除的方法 2:自己new一个包含主键的类,然后 attach附加 remove删除;3:使用db.Entry 修改状态删除4:EntityState的几种状态

      我们还是以订单表为例   1:系统推荐的方法,先查询出来,然后调用remove方法进行删除 我们删除id大于等于4的 static void Main(string[] args) { Delet ...

  2. Linux 定时任务crontab_014

    1.  crontab命令概念 crontab命令用于设置周期性被执行的指令.该命令从标准输入设备读取指令,并将其存放于“crontab”文件中,以供之后读取和执行. cron 系统调度进程. 可以使 ...

  3. R语言绘制带errorbar 的柱状图

    代码示例: data <- data.frame(mean = c(10, 15), sd = c(12, 17)) rownames(data) <- c("case" ...

  4. Quorumpeps 群体感应数据库简介

    群体感应的定义: 细菌能自发产生.释放一些特定的信号分子,并能感知其浓度变化,调节微生物的群体行为, 这一调控系统称为群体感应.细菌群体感应参与包括人类.动植物病原菌致病力在内的多种生物学功能的调节. ...

  5. ASP.NET MVC Castle Windsor 教程

    一.[转]ASP.NET MVC中使用Castle Windsor 二.[转]Castle Windsor之组件注册 平常用Inject比较多,今天接触到了Castle Windsor.本篇就来体验其 ...

  6. iOS:DKLiveBlur

    https://github.com/kronik/DKLiveBlur Sources of DKLiveBlur and Demo app to show live blur effect sim ...

  7. 怎样解决Java Web项目更改项目名后报错

    作为企业级开发最流行的工具,用Myeclipse开发java web程序无疑是最合适的,有时候,我们需要web工程的项目名,单方面的改动工程的项目名是会报错的,那么该如何改web工程项目名呢? 简 单 ...

  8. sp_replication_agent_checkup

    Transact-SQL 参考sp_replication_agent_checkup 检查每个分发数据库的复制代理程序,这些复制代理程序正在运行但在指定的心跳信号间隔内没有历史记录.此存储过程在分发 ...

  9. fork 至 “sys_clone" SyS_clone

    注:glibc-2.17中fork的相应系统调用是sys_clone及SyS_clone.有人说调用的是sys_fork,但是我持否定意见,如果我们向真的来发起系统调用可以使用syscall. for ...

  10. linux echo命令提示权限不够的解决办法

    该文章转载于此:http://blog.csdn.net/u010780613/article/details/51491237 问题描述:      在使用Ubuntu系统的时候,遇到这样的一个问题 ...