事件的捕获冒泡

在ReactEvent处理的最后,对抽象事件对象的队列进行了集中处理,调用了EventPluginHub.processAbstractEventQueue方法,该方法为每一个抽象事件对象执行了executeDispatchesAndRelease方法。

通过执行getPluginModuleForAbstractEvent,可以找到负责处理该类型的插件,其实现如下:

function getPluginModuleForAbstractEvent(abstractEvent) {
  if (abstractEvent.type.registrationName) {
    return registrationNames[abstractEvent.type.registrationName];
  } else {
    for (var phase in abstractEvent.type.phasedRegistrationNames) {
      if (!abstractEvent.type.phasedRegistrationNames.hasOwnProperty(phase)) {
        continue;
      }
      var PluginModule = registrationNames[
        abstractEvent.type.phasedRegistrationNames[phase]
      ];
      if (PluginModule) {
        return PluginModule;
      }
    }
  }
  return null;
}

registrationNames记录了每个不同类型的事件对应的插件(或者不同事件响应阶段的对应),因此,只要抽象事件对象的注册名称存在,就可以通过registrationName反查对应的pluginModule。而如果abtractEvent.type.registrationName不存在,则对比phasedRegistrationNames来查找相关的处理插件。

若找到的插件,且该插件定义了executeDispatch,则使用插件自定义的方法,否则的话,将调用EventPluginUtils中定义的默认executeDispatch方法,该方法就是执行了事件回调。

function executeDispatch(abstractEvent, listener, domID) {
  listener(abstractEvent, domID);
}

至于自定义executeDispatch的情况,以SimpleEventPlugin为例,executeDispatch时,如果回调执行的返回值为false,就会阻止事件冒泡。

 executeDispatch: function(abstractEvent, listener, domID) {
    var returnValue = listener(abstractEvent, domID);
    if (returnValue === false) {
      abstractEvent.stopPropagation();
      abstractEvent.preventDefault();
    }
  }

每一个AbstractEvent对象上,都保存了其事件回调函数,存放在_dispatchListeners中,里面的listener都是通过CallbackRegistery找到的与抽象事件对象及其响应阶段相对应的回调函数。

当抽象事件对象的回调处理完毕后(包括停止冒泡),React就会删除当前抽象事件对象上所有的回调函数信息,将抽象事件函数重新放回到缓冲池中。

results matching ""

    No results matching ""