ReactDOMTreeTraversal模块通过ReactDefaultInjection模块添加为EventPluginUtils模块的ComponentTree,供react合成事件对象获取_dispatchListeners、_dispatchInstances绑定回调函数及组件实例使用。
// ReactDOMTreeTraversal模块通过ReactDefaultInjection模块添加为EventPluginUtils模块的ComponentTree
// 供react合成事件对象获取_dispatchListeners、_dispatchInstances绑定回调函数及组件实例使用
'use strict';
var _prodInvariant = require('./reactProdInvariant');
var invariant = require('fbjs/lib/invariant');
// 获取组件实例instA、instB所共有的同个祖先组件实例
function getLowestCommonAncestor(instA, instB) {
!('_hostNode' in instA) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getNodeFromInstance: Invalid argument.') : _prodInvariant('33') : void 0;
!('_hostNode' in instB) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getNodeFromInstance: Invalid argument.') : _prodInvariant('33') : void 0;
var depthA = 0;
for (var tempA = instA; tempA; tempA = tempA._hostParent) {
depthA++;
}
var depthB = 0;
for (var tempB = instB; tempB; tempB = tempB._hostParent) {
depthB++;
}
// instA的层级比instB低,向上获取同instB平级的、instA的祖先组件
while (depthA - depthB > 0) {
instA = instA._hostParent;
depthA--;
}
while (depthB - depthA > 0) {
instB = instB._hostParent;
depthB--;
}
// 获取共有的祖先组件实例
var depth = depthA;
while (depth--) {
if (instA === instB) {
return instA;
}
instA = instA._hostParent;
instB = instB._hostParent;
}
// instA、instB不是由同一个祖先组件实例绘制,返回null
return null;
}
// 判断组件实例instA是否为instB的父组件
function isAncestor(instA, instB) {
!('_hostNode' in instA) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'isAncestor: Invalid argument.') : _prodInvariant('35') : void 0;
!('_hostNode' in instB) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'isAncestor: Invalid argument.') : _prodInvariant('35') : void 0;
while (instB) {
if (instB === instA) {
return true;
}
instB = instB._hostParent;
}
return false;
}
// 获取父组件
function getParentInstance(inst) {
!('_hostNode' in inst) ? process.env.NODE_ENV !== 'production' ? invariant(false, 'getParentInstance: Invalid argument.') : _prodInvariant('36') : void 0;
return inst._hostParent;
}
// 向上获取inst的直系父组件,执行fn函数,以获取该父组件的冒泡、捕获阶段的绑定回调函数
function traverseTwoPhase(inst, fn, arg) {
var path = [];
while (inst) {
path.push(inst);
inst = inst._hostParent;
}
var i;
for (i = path.length; i-- > 0;) {
fn(path[i], 'captured', arg);
}
for (i = 0; i < path.length; i++) {
fn(path[i], 'bubbled', arg);
}
}
// 参数argFrom鼠标移开状态的SyntheticMouseEvent类合成事件对象
// 参数argTo鼠标进入状态的SyntheticMouseEvent类合成事件对象
// 参数from鼠标移开的react组件实例
// 参数to鼠标进入的react组件实例
// 向上获取from的直系父组件(直到与to共有的祖先组件位置),执行fn,以获取该父组件绑定的鼠标离开事件的回调函数
// 向上获取to的直系父组件(直到与from共有的祖先组件位置),执行fn,以获取该父组件绑定的鼠标移入事件的回调函数
function traverseEnterLeave(from, to, fn, argFrom, argTo) {
var common = from && to ? getLowestCommonAncestor(from, to) : null;
var pathFrom = [];
while (from && from !== common) {
pathFrom.push(from);
from = from._hostParent;
}
var pathTo = [];
while (to && to !== common) {
pathTo.push(to);
to = to._hostParent;
}
var i;
for (i = 0; i < pathFrom.length; i++) {
fn(pathFrom[i], 'bubbled', argFrom);
}
for (i = pathTo.length; i-- > 0;) {
fn(pathTo[i], 'captured', argTo);
}
}
module.exports = {
// isAncestor(instA,instB)判断组件实例instA是否为instB的父组件
isAncestor: isAncestor,
// getLowestCommonAncestor(instA,instB)获取组件实例instA、instB所共有的同个祖先组件实例
getLowestCommonAncestor: getLowestCommonAncestor,
// getParentInstance(inst)获取父组件
getParentInstance: getParentInstance,
// traverseTwoPhase(inst,fn,arg)遍历inst的直系父组件,执行fn函数,以获取该父组件的冒泡、捕获阶段的绑定回调函数
traverseTwoPhase: traverseTwoPhase,
// traverseEnterLeave(from,to,fn,argFrom,argTo)
// 遍历rom的直系父组件(直到与to共有的祖先组件位置),执行fn,以获取该父组件绑定的鼠标离开事件的回调函数
// 遍历to的直系父组件(直到与from共有的祖先组件位置),执行fn,以获取该父组件绑定的鼠标移入事件的回调函数
traverseEnterLeave: traverseEnterLeave
};
本文介绍React中事件处理机制的关键部分,包括如何通过组件树查找共同祖先、确定父子关系、获取父组件以及遍历组件树来触发事件处理函数。
133

被折叠的 条评论
为什么被折叠?



