EventPluginHub.injection.getInstanceHandle().traverseTwoPhase方法
找到这个方法 ReactInstanceHandles 类。
<!--
EventPluginHub.injection.getInstanceHandle()方法返回一个InstanceHandle。而InstanceHandle 是调用 injectInstanceHandle方法注入进来的。
ReactDefaultInjection类中注入的。
注入的是 ReactInstanceHandles 类。
所以EventPluginHub.injection.getInstanceHandle().traverseTwoPhase()方法实际是调用了ReactInstanceHandles类的下边方法:
-->
<!--
targetID:就是触发事件的源元素的id。
cb是一个方法 EventPropagators模块里的accumulateDirectionalDispatches方法。
-->
traverseTwoPhase: function (targetID, cb, arg) {
if (targetID) {
traverseParentPath('', targetID, cb, arg, true, false);
traverseParentPath(targetID, '', cb, arg, false, true);
}
}
如上traverseTwoPhase方法是调用了如下方法:
关于traverseParentPath方法的源码分析
traverseParentPath('', targetID, cb, arg, true, false);
<!--
这个方法会根据触发事件的元素的id,从根元素一直找到targetID。
收集起来。把这一段的全部
具体React是怎么做的
找到一个id就调用一次EventPropagators模块里的accumulateDirectionalDispatches方法。
看一下EventPropagators模块里的accumulateDirectionalDispatches方法
-->
function accumulateDirectionalDispatches(domID, upwards, event) {
<!--
根据domID找到存储在 listenerBank 中的侦听器
-->
var listener = listenerAtPhase(domID, event, phase);
<!--
把侦听器放入event的_dispatchListeners属性中。这个是取的了捕获阶段定义的事件。
listenerBank中存储侦听器的方式是
{
onClick:{
.0:f(),
.0.1:f()
}
}
每一种事件会将该类型的侦听器存储在一块。
-->
if (listener) {
event._dispatchListeners = accumulateInto(event._dispatchListeners, listener);
event._dispatchIDs = accumulateInto(event._dispatchIDs, domID);
}
}
分割线
==============================================================
traverseParentPath('', targetID, cb, arg, true, false);
<!--
这个方法与上边的方法相反,收集的是冒泡过程的事件侦听器。
-->
经过上边的处理之后合成事件event中就存储了捕获阶段和冒泡阶段会触发的全部的侦听器。到此合成事件全部完成了。合成事件会被放在事件队列被执行。
ReactEventEmitterMixi模块的合成队列处理
function runEventQueueInBatch(events) {
<!--
合成事件入队
-->
EventPluginHub.enqueueEvents(events);
<!--
合成事件队列执行
-->
EventPluginHub.processEventQueue(false);
}