jQuery源码分析之Event事件分析

2019-06-06 02:40:18王冬梅

   if (elem.nodeType == 3 || elem.nodeType == 8)  return undefined;
   var val, ret, fn = jQuery.isFunction(elem[type] || null),
   // 如果data参数传进入的不是浏览器的event对象的话,event变量为true.
  //如果data参数本身是娄组,那么第一个元素不是 浏览器的event对象时为true.
  //对于event为true。即没有event传进入,先构建一个伪造的event对象存在 data[0]。
  event = !data[0] || !data[0].preventDefault;
  // 在没有传入event对象的情况下,构建伪造event对象。
  if (event) {//存到数组中的第一个             ④
     data.unshift( { type : type,target : elem,
       preventDefault : function() {},stopPropagation :
function() {}, timeStamp : now()  });
    data[0][expando] = true; // 不需要修正伪造的event对象
    }
   data[0].type = type; //防止事件名出错
  //表现会进行事件注册函数的分类(命名空间)执行。不是所有的。
    if (exclusive) data[0].exclusive = true;
  
  //与prototype等传统的处理 方式不一样,没有采用fireEvent来
  //来fire通过注册到浏览器事件中的事件处理方法。
  //这里分了三步,先fire 通过jQuery.event.add来注册的事件,这个事件
  //有可能是自定义的事件(没有注册到浏览器事件中)。
  //第二步 是fire通过elem.onclick方式注册的事件的本地处理函数
   //第三步是fire默认的事件处理方式(在本地的onclick的方式注册
   //不存在的情况下)。  
// 这里是触发通过jQuery.event.add来注册的事件,
   var handle = jQuery.data(elem, "handle");      ⑤
   if (handle)val = handle.apply(elem, data); //这里data分成多个参数
  //处理触发通过elem.onfoo=function()这样的注册本地处理方法,
  //但是是 对于links 's .click()不触发,这个不会执行通过addEvent
  //方式注册的事件处理方式。     
  if ((!fn || (jQuery.nodeName(elem, 'a') && type == "click")) ⑥
     && elem["on"+ type]&& elem["on"+type].apply(elem,data) === false)
   val = false;
//额外的函 数参数的开始几个是通过data给定的。这里会把伪造加上的event给去掉。
//它的最后一个参数是一系列的事件处理函数返回的结果,一般为 bool值
//这个函数可以根据这个结果来处理一个扫尾的工作。
  if (event) data.shift();
// 处理触发extra给定的函数处理。
  if (extra && jQuery.isFunction(extra)) {           ⑦
    ret = extra.apply(elem, val == null ? data : data.concat(val));
    //如果这个函数有返回值,那么trigger的返回值就是它的返回值
    //没有的 话就是串连的事件处理函数的最后一个返回值。一般为bool