注入平台事件插件
DOMEventPluginOrder
injectEventPluginOrder方法的入参, 规定注入事件插件名称的顺序,是一个写死的数组
typescript
const DOMEventPluginOrder = [
'ResponderEventPlugin',
'SimpleEventPlugin',
'EnterLeaveEventPlugin',
'ChangeEventPlugin',
'SelectEventPlugin',
'BeforeInputEventPlugin',
];Plugin
injectEventPluginsByName方法的入参,就是一个个具体的事件的插件,具体的结构以change事件为例:
typescript
const ChangeEventPlugin = {
// 具体的eventTypes
eventTypes: {
change: {
// 事件分为2个阶段,捕获阶段和冒泡阶段
// 一般情况下 我们使用的都是冒泡阶段的事件
phasedRegistrationNames: {
// 冒泡阶段
bubbled: 'onChange',
// 捕获阶段
captured: 'onChangeCapture',
},
// 依赖 react在绑定change事件的时候,同时还会为当前change事件绑定依赖的事件
dependencies: [
TOP_BLUR,
TOP_CHANGE,
TOP_CLICK,
TOP_FOCUS,
TOP_INPUT,
TOP_KEY_DOWN,
TOP_KEY_UP,
TOP_SELECTION_CHANGE,
],
},
},
_isInputEventSupported: isInputEventSupported,
// 用来生成事件对象的
extractEvents: function(
topLevelType,
targetInst,
nativeEvent,
nativeEventTarget,
) {
},
};injectEventPluginOrder
injectEventPluginOrder方法做了什么?只是单纯的将DOMEventPluginOrder变量进行了一次拷贝, 赋值给了eventPluginOrder
typescript
export function injectEventPluginOrder(
injectedEventPluginOrder: EventPluginOrder,
): void {
// 克隆一份 这样的话可以在当前文件动态修改
eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder);
}injectEventPluginsByName
这个方法主要做了2件事
- 生成namesToPlugins对象的数据
- 调用recomputePluginOrdering
typescript
export function injectEventPluginsByName(
injectedNamesToPlugins: NamesToPlugins,
): void {
let isOrderingDirty = false;
for (const pluginName in injectedNamesToPlugins) {
if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {
continue;
}
const pluginModule = injectedNamesToPlugins[pluginName];
if (
!namesToPlugins.hasOwnProperty(pluginName) ||
namesToPlugins[pluginName] !== pluginModule
) {
namesToPlugins[pluginName] = pluginModule;
isOrderingDirty = true;
}
}
if (isOrderingDirty) {
recomputePluginOrdering();
}
}namesToPlugins
typescript
const namesToPlugins = {
ChangeEventPlugin: {
eventTypes: {
change: {
phasedRegistrationNames: {
bubbled: 'onChange',
captured: 'onChangeCapture',
},
dependencies: [ ... ]
}
},
extractEvents: () => {}
}
}recomputePluginOrdering
typescript
function recomputePluginOrdering(): void {
for (const pluginName in namesToPlugins) {
// 拿到事件插件的值
const pluginModule = namesToPlugins[pluginName];
// 计算索引,这里不存在pluginIndex等于0的索引,因为ResponderEventPlugin不在namesToPlugins里面
const pluginIndex = eventPluginOrder.indexOf(pluginName);
// 将pluginModule按顺序放置在plugins数组里面
// plugins 的索引为0是空的,因为没有ResponderEventPlugin
plugins[pluginIndex] = pluginModule;
const publishedEvents = pluginModule.eventTypes;
for (const eventName in publishedEvents) {
// 这里的 eventName 就是 eventTypes的键
// 比如 change事件,就是 ‘change’
publishEventForPlugin(
// { phasedRegistrationNames: {...}, dependencies: [...] }
publishedEvents[eventName],
// { eventTypes: ..., extractEvents: () => { ... } }
pluginModule,
// change
eventName,
)
}
}
}publishEventForPlugin
typescript
function publishEventForPlugin(
dispatchConfig: DispatchConfig,
pluginModule: PluginModule<AnyNativeEvent>,
eventName: string,
): boolean {
eventNameDispatchConfigs[eventName] = dispatchConfig;
// phasedRegistrationNames 就是事件阶段的名称 bubbled 、captured 等
const phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;
if (phasedRegistrationNames) {
for (const phaseName in phasedRegistrationNames) {
// phaseName 就是 bubbled 、captured
if (phasedRegistrationNames.hasOwnProperty(phaseName)) {
// phasedRegistrationNames 就是 React Dom节点接收的事件的props的名称
// 例如 onChange onClick
const phasedRegistrationName = phasedRegistrationNames[phaseName];
publishRegistrationName(
// onChange
phasedRegistrationName,
// { eventTypes: ..., extractEvents: () => { ... } }
pluginModule,
// change
eventName,
);
}
}
return true;
} else if (dispatchConfig.registrationName) {
publishRegistrationName(
dispatchConfig.registrationName,
pluginModule,
eventName,
);
return true;
}
return false;
}publishRegistrationName
typescript
function publishRegistrationName(
registrationName: string,
pluginModule: PluginModule<AnyNativeEvent>,
eventName: string,
): void {
registrationNameModules[registrationName] = pluginModule;
registrationNameDependencies[registrationName] = pluginModule.eventTypes[eventName].dependencies;
}生成的数据结构如下
namesToPlugin

registrationNameModules

registrationNameDependencies

eventNameDispatchConfigs
