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 };