当前位置: 首页 > news >正文

php 做网站新网站百度多久收录

php 做网站,新网站百度多久收录,珠海网站建设哪个好薇,一个网站做数据分析要多少钱event 事件系统初始化 1 )概述 react事件系统比较的复杂,它是基于dom的事件系统在dom事件系统上面进行了一个深度的封装它里面的很多实现逻辑都是自由的一套在初始化 react-dom 的源码的时候,会为react的事件系统注入 reactdom 相关的一些插…

event 事件系统初始化


1 )概述

  • react事件系统比较的复杂,它是基于dom的事件系统
  • 在dom事件系统上面进行了一个深度的封装
  • 它里面的很多实现逻辑都是自由的一套
  • 在初始化 react-dom 的源码的时候,会为react的事件系统注入 reactdom 相关的一些插件
  • 因为react事件系统,它有一个独立的模块,这个模块是一个公用性质的模块
  • 就是说它是可以给 react-dom 用,也可以给 react-native 用
  • 不同平台它们的事件系统可能会不一样,这个时候就对于不同的平台
  • 它们要去使用同一个 event 模块的时候,使用注入的方式来注入一些跟平台相关的逻辑在里面
  • 在这个模块,也是有一部分核心的内容是全平台通用的,这部分内容是react抽象出来的
  • 我们关注平台插件注入的一个流程,以及它插入之后到底做了什么事情
    • 首先要确定一个插件注入的顺序
      • 因为在react当中它的插件执行是会按照顺序来的
      • 如果不按顺序来,可能会出现一定的问题
    • 然后要注入插件模块
    • 最后要计算 registationNameModules 等属性
  • 在之前 completeWork 的时候,初始化 dom 节点的时候
    • 要去绑定 props 对应的 dom 的 attributes 的时候
    • 就有遇到过这个 registationNameModules 属性

2 )源码

定位到 packages/react-dom/src/client/ReactDOM.js#L20

import './ReactDOMClientInjection';

再次定位到 packages/react-dom/src/client/ReactDOMClientInjection.js

/*** Copyright (c) Facebook, Inc. and its affiliates.** This source code is licensed under the MIT license found in the* LICENSE file in the root directory of this source tree.*/import * as EventPluginHub from 'events/EventPluginHub';
import * as EventPluginUtils from 'events/EventPluginUtils';import {getFiberCurrentPropsFromNode,getInstanceFromNode,getNodeFromInstance,
} from './ReactDOMComponentTree';
import BeforeInputEventPlugin from '../events/BeforeInputEventPlugin';
import ChangeEventPlugin from '../events/ChangeEventPlugin';
import DOMEventPluginOrder from '../events/DOMEventPluginOrder';
import EnterLeaveEventPlugin from '../events/EnterLeaveEventPlugin';
import SelectEventPlugin from '../events/SelectEventPlugin';
import SimpleEventPlugin from '../events/SimpleEventPlugin';/*** Inject modules for resolving DOM hierarchy and plugin ordering.*/
EventPluginHub.injection.injectEventPluginOrder(DOMEventPluginOrder);
EventPluginUtils.setComponentTree(getFiberCurrentPropsFromNode,getInstanceFromNode,getNodeFromInstance,
);/*** Some important event plugins included by default (without having to require* them).*/
EventPluginHub.injection.injectEventPluginsByName({SimpleEventPlugin: SimpleEventPlugin,EnterLeaveEventPlugin: EnterLeaveEventPlugin,ChangeEventPlugin: ChangeEventPlugin,SelectEventPlugin: SelectEventPlugin,BeforeInputEventPlugin: BeforeInputEventPlugin,
});
  • 看到它 import 了一大堆的东西,后续只是调用了3个方法

    • injectEventPluginOrder
    • setComponentTree 这个先跳过
    • injectEventPluginsByName
  • 看下 EventPluginHub.injection.injectEventPluginOrder(DOMEventPluginOrder);

    • 这个 DOMEventPluginOrder
      // packages/react-dom/src/events/DOMEventPluginOrder.js
      const DOMEventPluginOrder = ['ResponderEventPlugin','SimpleEventPlugin','EnterLeaveEventPlugin','ChangeEventPlugin','SelectEventPlugin','BeforeInputEventPlugin',
      ];export default DOMEventPluginOrder;
      
      • 它单纯的 export 出来了一个数组
      • 这个数组可以看到有6项,每一项都以一个 Plugin 为结尾的
      • 这些 plugin 都是在 react-dom 这个环境当中要用到的 plugin
      • 这边只是用来定义这些 plugin 它的一个顺序
  • 后续 EventPluginHub.injection.injectEventPluginsByName 这个方法的参数

    • 发现这里少了一个 ResponderEventPlugin 先不管
  • 关注下 EventPluginHub 这个模块下的 injection

    /*** Methods for injecting dependencies.*/
    export const injection = {/*** @param {array} InjectedEventPluginOrder* @public*/injectEventPluginOrder,/*** @param {object} injectedNamesToPlugins Map from names to plugin modules.*/injectEventPluginsByName,
    };
    
    • 上述内部这两个方法来自 ./EventPluginRegistry.js 进入
      /*** Injects an ordering of plugins (by plugin name). This allows the ordering
      * to be decoupled from injection of the actual plugins so that ordering is
      * always deterministic regardless of packaging, on-the-fly injection, etc.
      *
      * @param {array} InjectedEventPluginOrder
      * @internal
      * @see {EventPluginHub.injection.injectEventPluginOrder}
      */
      export function injectEventPluginOrder(injectedEventPluginOrder: EventPluginOrder,
      ): void {invariant(!eventPluginOrder,'EventPluginRegistry: Cannot inject event plugin ordering more than ' +'once. You are likely trying to load more than one copy of React.',);// Clone the ordering so it cannot be dynamically mutated.// 克隆一个可动态修改的数组eventPluginOrder = Array.prototype.slice.call(injectedEventPluginOrder);recomputePluginOrdering();
      }/*** Injects plugins to be used by `EventPluginHub`. The plugin names must be
      * in the ordering injected by `injectEventPluginOrder`.
      *
      * Plugins can be injected as part of page initialization or on-the-fly.
      *
      * @param {object} injectedNamesToPlugins Map from names to plugin modules.
      * @internal
      * @see {EventPluginHub.injection.injectEventPluginsByName}
      */
      export function injectEventPluginsByName(injectedNamesToPlugins: NamesToPlugins,
      ): void {let isOrderingDirty = false;// 遍历对象上的 pluginNamefor (const pluginName in injectedNamesToPlugins) {// 非本身拥有,则跳过if (!injectedNamesToPlugins.hasOwnProperty(pluginName)) {continue;}const pluginModule = injectedNamesToPlugins[pluginName];if (!namesToPlugins.hasOwnProperty(pluginName) ||namesToPlugins[pluginName] !== pluginModule) {invariant(!namesToPlugins[pluginName],'EventPluginRegistry: Cannot inject two different event plugins ' +'using the same name, `%s`.',pluginName,);// 重新注入 modulenamesToPlugins[pluginName] = pluginModule;isOrderingDirty = true; // 设置这个 isOrderingDirty 状态}}if (isOrderingDirty) {recomputePluginOrdering(); // 调用这个方法}
      }
      
      • 上述 namesToPlugins 本来就是一个 空的对象
      • 进入 recomputePluginOrdering
        /*** Recomputes the plugin list using the injected plugins and plugin ordering.
        *
        * @private
        */
        function recomputePluginOrdering(): void {if (!eventPluginOrder) {// Wait until an `eventPluginOrder` is injected.return;}// 遍历在 injectEventPluginsByName 方法中处理好的 namesToPlugins 对象for (const pluginName in namesToPlugins) {const pluginModule = namesToPlugins[pluginName];const pluginIndex = eventPluginOrder.indexOf(pluginName); // 拿到注入顺序invariant(pluginIndex > -1,'EventPluginRegistry: Cannot inject event plugins that do not exist in ' +'the plugin ordering, `%s`.',pluginName,);// plugins 初始化的时候,是一个空的数组,存在则跳过if (plugins[pluginIndex]) {continue;}invariant(pluginModule.extractEvents,'EventPluginRegistry: Event plugins must implement an `extractEvents` ' +'method, but `%s` does not.',pluginName,);// 注意,这里的 index 是从 eventPluginOrder 的顺序插入的,而非有序插入,这里可能会造成数组中的某几项为 undefinedplugins[pluginIndex] = pluginModule;const publishedEvents = pluginModule.eventTypes; // click, change, focus 等类型for (const eventName in publishedEvents) {invariant(// 注意这里publishEventForPlugin(publishedEvents[eventName], // 注意这个数据结构pluginModule,eventName,),'EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.',eventName,pluginName,);}}
        }
        
        • 关于 eventTypes
          const eventTypes = {// 这个 对应 dom 中的真实事件,比如 change 事件 document.addEventListener('change', () => {})// 这个 change 代表 event name 存在// 这个 value 对应上面的 dispatchConfigchange: {// 事件的阶段,有冒泡和捕获 两个阶段,对应react中 使用的事件 props 名称phasedRegistrationNames: {bubbled: 'onChange',captured: 'onChangeCapture', // 这个 props 不常用,用于在绑定捕获阶段的事件监听},// 监听 change 事件的同时,需要依赖绑定下面的事件dependencies: [TOP_BLUR,TOP_CHANGE,TOP_CLICK,TOP_FOCUS,TOP_INPUT,TOP_KEY_DOWN,TOP_KEY_UP,TOP_SELECTION_CHANGE,],},
          };
          
          • eventTypes 这个对象里面还可以再加其他事件,以上是初始化时候挂载处理的 change 事件,参考下面
        • 对于 packages/react-dom/src/events/SimpleEventPlugin.js 里面监听了大部分的常用事件
          • 在这里面 会生成一个 type, 定位到 #L143 (143行)
            function addEventTypeNameToConfig([topEvent, event]: EventTuple,isInteractive: boolean,
            ) {const capitalizedEvent = event[0].toUpperCase() + event.slice(1);const onEvent = 'on' + capitalizedEvent;// 注意这里const type = {phasedRegistrationNames: {bubbled: onEvent,captured: onEvent + 'Capture',},dependencies: [topEvent],isInteractive,};eventTypes[event] = type;topLevelEventsToDispatchConfig[topEvent] = type;
            }
            
        • 进入 publishEventForPlugin
          /*** Publishes an event so that it can be dispatched by the supplied plugin.
          *
          * @param {object} dispatchConfig Dispatch configuration for the event.
          * @param {object} PluginModule Plugin publishing the event.
          * @return {boolean} True if the event was successfully published.
          * @private
          */
          function publishEventForPlugin(dispatchConfig: DispatchConfig,pluginModule: PluginModule<AnyNativeEvent>,eventName: string,
          ): boolean {invariant(!eventNameDispatchConfigs.hasOwnProperty(eventName),'EventPluginHub: More than one plugin attempted to publish the same ' +'event name, `%s`.',eventName,);// 这里 eventNameDispatchConfigs 的结构// { change: ChangeEventPlugin.eventTypes.change }eventNameDispatchConfigs[eventName] = dispatchConfig;// 获取事件 内部的 phasedRegistrationNamesconst phasedRegistrationNames = dispatchConfig.phasedRegistrationNames;if (phasedRegistrationNames) {for (const phaseName in phasedRegistrationNames) {if (phasedRegistrationNames.hasOwnProperty(phaseName)) {const phasedRegistrationName = phasedRegistrationNames[phaseName];publishRegistrationName(phasedRegistrationName,pluginModule,eventName,);}}return true;} else if (dispatchConfig.registrationName) {publishRegistrationName(dispatchConfig.registrationName,pluginModule,eventName,);return true;}return false;
          }
          
          • 进入 publishRegistrationName
            /*** Publishes a registration name that is used to identify dispatched events.
            *
            * @param {string} registrationName Registration name to add.
            * @param {object} PluginModule Plugin publishing the event.
            * @private
            */
            function publishRegistrationName(registrationName: string,pluginModule: PluginModule<AnyNativeEvent>,eventName: string,
            ): void {invariant(!registrationNameModules[registrationName],'EventPluginHub: More than one plugin attempted to publish the same ' +'registration name, `%s`.',registrationName,);// onChange: ChangeEventPluginregistrationNameModules[registrationName] = pluginModule;// onChange: [TOP_BLUR ...]registrationNameDependencies[registrationName] =pluginModule.eventTypes[eventName].dependencies;if (__DEV__) {const lowerCasedName = registrationName.toLowerCase();possibleRegistrationNames[lowerCasedName] = registrationName;if (registrationName === 'onDoubleClick') {possibleRegistrationNames.ondblclick = registrationName;}}
            }
            
        • 关于 const publishedEvents = pluginModule.eventTypes; 这里,可参考 packages/react-dom/src/events/ChangeEventPlugin.js#L258
          const ChangeEventPlugin = {eventTypes: eventTypes,_isInputEventSupported: isInputEventSupported, // 这个 _isInputEventSupported 是一个私有标志位// 这个 extractEvents 是生成事件,比如 onChange 事件对应的事件对象的extractEvents: function(topLevelType,targetInst,nativeEvent,nativeEventTarget,) {const targetNode = targetInst ? getNodeFromInstance(targetInst) : window;let getTargetInstFunc, handleEventFunc;if (shouldUseChangeEvent(targetNode)) {getTargetInstFunc = getTargetInstForChangeEvent;} else if (isTextInputElement(targetNode)) {if (isInputEventSupported) {getTargetInstFunc = getTargetInstForInputOrChangeEvent;} else {getTargetInstFunc = getTargetInstForInputEventPolyfill;handleEventFunc = handleEventsForInputEventPolyfill;}} else if (shouldUseClickEvent(targetNode)) {getTargetInstFunc = getTargetInstForClickEvent;}if (getTargetInstFunc) {const inst = getTargetInstFunc(topLevelType, targetInst);if (inst) {const event = createAndAccumulateChangeEvent(inst,nativeEvent,nativeEventTarget,);return event;}}if (handleEventFunc) {handleEventFunc(topLevelType, targetNode, targetInst);}// When blurring, set the value attribute for number inputsif (topLevelType === TOP_BLUR) {handleControlledInputBlur(targetNode);}},
          };
          
  • 通过以上操作,插入了所有的plugin之后,形成了这边的几个变量

    • let eventPluginOrder: EventPluginOrder = null; 数据结构如下
      ['ResponderEventPlugin', 'SimpleEventPlugin', 'EnterLeaveEventPlugin', 'ChangeEventPlugin', 'SelectEventPlugin', 'BeforeInputEventPlugin'
      ];
      
    • export const plugins = []; 数据结构如下
      [{eventTypes:{},extractEvents:function,otherProps},....
      ]
      
    • export const eventNameDispatchConfigs = {};
      {click:{dependencies:['click'],phasedRegistrationNames:{bubbled: "onClick"captured: "onClickCapture"},isInteractive: true}
      }
      
    • const namesToPlugins: NamesToPlugins = {};
      {SimpleEventPlugin:{eventTypes:{},extractEvents:function,otherProps},// ...其他插件
      }
      
    • export const registrationNameModules = {};
      {onClick:{eventTypes:{},extractEvents:function,otherProps},...
      }
      
    • export const registrationNameDependencies = {};
      {onClick: ["click"],onChange: ["blur", "change", "click", "focus", "input", "keydown",keyup", "selectionchange],....
      }
      
  • 把这几个变量维护好之后,后面可以很方便的进行一些事件绑定相关的操作

  • 对于事件注入这个模块,是初始化事件的前置任务

  • 重点关注最终拿到的几个完成注册之后的变量的数据格式

  • 以上就是把整个事件的插件它注入到react事件系统当中的过程

http://www.ds6.com.cn/news/32562.html

相关文章:

  • 企业为什么要分析环境成都网站seo技术
  • 网站 keyword title 字数精准数据营销方案
  • 做1688网站需要懂英语吗网站推广工具有哪些
  • 解决wordpress更改新域名后网站不能访问的问题口碑营销案例2021
  • 设计师接私活的网站跨境电商培训
  • 网站首页的动态视频怎么做的汉中网站seo
  • 做网站和商城有什么好处长春网站建设公司哪家好
  • 求做网站seo培训优化
  • 网站限时抢购怎么做整合营销策划方案模板
  • 互动案例的网站外贸网站制作公司
  • 成都诗和远方网站建设重庆seo培训
  • 网站做动态图片不显示企业网络营销案例
  • 营销型网站软件seo建站公司推荐
  • 网站开发者yotoon什么叫关键词
  • 网站添加站长统计代码自媒体有哪些平台
  • 镇江网站建设介绍服务关键词优化seo优化
  • wordpress 博客 地址怎么优化一个网站关键词
  • 手机网站制作步骤搜索引擎优化的基本方法
  • 保定网页设计网站建设推广优化
  • 静态网页设计报告搜索引擎优化教材答案
  • 购物网页设计论文建站网站关键词优化
  • 哪些网站可以加锚文本高清网站推广免费下载
  • 头像在线制作生成器seo点击工具
  • 中铁建设门户网员工登录搜索引擎优化是指
  • wordpress登录页面显示ip武汉网络推广seo
  • 网站建设需要哪些技术人员自助建站系统个人网站
  • 招聘去建设赌博类网站seo关键字排名优化
  • 南海网站建设多少钱域名注册免费
  • 做网站高亮seo评测论坛
  • 网站建设需求指引免费行情网站app大全