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

网站建设完善方案网络营销和推广做什么

网站建设完善方案,网络营销和推广做什么,深圳做网站乐云seo598,做网站 pc端与手机端兼容热身准备 明确几个概念 在React17.0.3版本中: 所有事件都是委托在id root的DOM元素中(网上很多说是在document中,17版本不是了);在应用中所有节点的事件监听其实都是在id root的DOM元素中触发;React自…

热身准备

明确几个概念

React@17.0.3版本中:

  • 所有事件都是委托在id = root的DOM元素中(网上很多说是在document中,17版本不是了);
  • 在应用中所有节点的事件监听其实都是在id = root的DOM元素中触发;
  • React自身实现了一套事件冒泡捕获机制;
  • React实现了合成事件SyntheticEvent
  • React17版本不再使用事件池了(网上很多说使用了对象池来管理合成事件对象的创建销毁,那是16版本及之前);
  • 事件一旦在id = root的DOM元素中委托,其实是一直在触发的,只是没有绑定对应的回调函数;

事件系统角色划分

  • 事件注册:registerEvents
  • 事件监听:listenToAllSupportedEvents
  • 事件合成:SyntheticBaseEvent
  • 事件派发:dispatchEvent

事件注册

事件注册是自执行的,也就是React自身进行调用的:

// 注册React事件
registerSimpleEvents();registerEvents$2();
registerEvents$1();
registerEvents$3();
registerEvents(); 

React事件就是在组件中调用的onClick这种写法的事件。上面分为5个函数写,主要是区分不同的事件注册逻辑,但是最后都会添加到allNativeEventsSet数据结构中

registerSimpleEvents

这里会注册大部分事件,它们在React被定义为顶级事件。

它们分为三类:

  • 离散事件:discreteEvent,常见的如:click, keyup, change
  • 用户阻塞事件:userBlocking,常见的如:dragEnter, mouseMove, scroll
  • 连续事件:continuous,常见的如:error, progress, load, ; 它们的优先级排序:

0:离散事件, 1:用户阻塞事件, 2:连续事件

它们会注册冒泡和捕获阶段两个事件。

registerEvents$2

注册类似onMouseEnteronMouseLeave单阶段事件,只注册冒泡阶段事件。

registerEvents$1

注册onChange相关事件,注册冒泡和捕获阶段两个事件。

registerEvents$3

注册onSelect相关事件,注册冒泡和捕获阶段两个事件。

registerEvents

注册onBeforeInputonCompositionUpdate等相关事件,注册冒泡和捕获阶段两个事件。

事件监听

在React源码系列之二:React的渲染机制曾提到过,React在开始渲染前,会为应用创建一个fiberRoot作为应用的根节点。在创建fiberRoot还会做一件事,就是

listenToAllSupportedEvents(rootContainerElement); 

从字面就能理解这个函数是做事件监听的,其中rootContainerElement参数就是应用中的id = root的DOM元素。

该函数主要遍历上面事件注册添加到allNativeEvents的事件,按照一定规则,区分冒泡阶段,捕获阶段,区分有无副作用进行监听,监听的api还是addEventListener:

// 监听冒泡阶段事件
function addEventBubbleListener(target, eventType, listener) {target.addEventListener(eventType, listener, false);return listener;
}
// 监听捕获阶段事件
function addEventCaptureListener(target, eventType, listener) {target.addEventListener(eventType, listener, true);return listener;
} 

代码中的target就是id = root的DOM元素。

注意,上面监听的listener是一个事件派发器,并不是真实的浏览器事件或你写的事件回调函数。 不要搞混淆了。

事件派发

上面提到,事件一旦在id = root的DOM元素中委托,其实是一直在触发的,只是没有绑定对应的回调函数。

意思是,当我们把鼠标移入我们的应用页面中时,这时就在派发事件了,因为页面的DOM元素是有监听mousemove之类的事件的。

那问题来了,React是如何得知我们给事件绑定了回调函数并触发对应的回调函数的?

带着这个问题我们来研究下事件派发

要讲事件派发,还得提下事件监听阶段监听的listener,它实际是下面这玩意:

function createEventListenerWrapperWithPriority(targetContainer, domEventName, eventSystemFlags) {var eventPriority = getEventPriorityForPluginSystem(domEventName);var listenerWrapper;switch (eventPriority) {case DiscreteEvent:listenerWrapper = dispatchDiscreteEvent;break;case UserBlockingEvent:listenerWrapper = dispatchUserBlockingUpdate;break;case ContinuousEvent:default:listenerWrapper = dispatchEvent;break;}return listenerWrapper.bind(null, domEventName, eventSystemFlags, targetContainer);
} 

和事件注册一样,listener也分为dispatchDiscreteEvent, dispatchUserBlockingUpdate, dispatchEvent三种。它们之间的主要区别是执行优先级,还有discreteEvent涉及到要清除之前的discreteEvent问题,所以做了区分。但是它们最后都会调用dispatchEvent。相关参考视频讲解:进入学习

所以事件派发的角色应该是dispatchEvent

function dispatchEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent) {var allowReplay = true;allowReplay = (eventSystemFlags & IS_CAPTURE_PHASE) === 0;// 如果有离散事件正在执行,会排队,顺序执行if (allowReplay && hasQueuedDiscreteEvents() && isReplayableDiscreteEvent(domEventName)) {domEventName, eventSystemFlags, targetContainer, nativeEvent);return;}// 尝试事件派发,如果成功,就不用执行下面的代码了var blockedOn = attemptToDispatchEvent(domEventName, eventSystemFlags, targetContainer, nativeEvent);// 尝试事件派发成功if (blockedOn === null) {if (allowReplay) {// 清除连续事件队列clearIfContinuousEvent(domEventName, nativeEvent);}return;}if (allowReplay) {if (isReplayableDiscreteEvent(domEventName)) {queueDiscreteEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent);return;}if (queueIfContinuousEvent(blockedOn, domEventName, eventSystemFlags, targetContainer, nativeEvent)) {return;} clearIfContinuousEvent(domEventName, nativeEvent);} dispatchEventForPluginEventSystem(domEventName, eventSystemFlags, nativeEvent, null, targetContainer);
} 

介绍下dispatchEvent的几个参数:

  • domEventName: DOM事件名称,如:click,不是onClick
  • eventSystemFlags:事件系统标记;
  • targetContainerid=root的DOM元素;
  • nativeEvent:原生事件(来自addEventListener);

attemptToDispatchEvent中, 根据nativeEvent.target找到真正触发事件的DOM元素,并根据DOM元素找到对应的fiber节点,判断fiber节点的类型以及是否已渲染来决定是否要派发事件。

在一系列判断通过后,就开始真正的事件处理了:

function dispatchEventsForPlugins(domEventName, eventSystemFlags, nativeEvent, targetInst, targetContainer) {// 获取触发事件的DOM元素var nativeEventTarget = getEventTarget(nativeEvent);// 初始化事件派发队列var dispatchQueue = [];// 合成事件extractEvents$5(dispatchQueue, domEventName, targetInst, nativeEvent, nativeEventTarget, eventSystemFlags);// 按事件派发队列执行事件派发processDispatchQueue(dispatchQueue, eventSystemFlags);
} 

extractEvents$5中会进行事件合成,放在下面单独讲。

processDispatchQueue会根据事件阶段(冒泡或捕获)来决定是正序还是倒序遍历合成事件中的listeners

接下来就比较简单了。 遍历listeners执行上面的listener

合成事件

在合成事件中,会根据domEventName来决定使用哪种类型的合成事件。

click为例,当我们点击页面的某个元素时,React会根据原生事件nativeEvent找到触发事件的DOM元素和对应的fiber节点。并以该节点为孩子节点往上查找,找到包括该节点及以上所有的click回调函数创建dispatchListener,并添加到listeners数组中。

// dispatchListener
{instance: instance,// 事件所在的fiber节点listener: listener,// 事件回调函数currentTarget: currentTarget// 事件对应的DOM元素} 

当向上查找完成后,会基于click类型的合成事件类创建事件

// 创建合成事件实例
var _event = new SyntheticEventCtor(reactName, reactEventType, null, nativeEvent, nativeEventTarget);
// 事件派发队列添加事件
dispatchQueue.push({event: _event, // 合成事件实例listeners: _listeners// 同类型事件的集合数组
}); 

看下SyntheticEventCtor

// Interface根据事件类型有所不同
function createSyntheticEvent(Interface) {// 合成事件构造函数function SyntheticBaseEvent(reactName, reactEventType, targetInst, nativeEvent, nativeEventTarget) {this._reactName = reactName;this._targetInst = targetInst;this.type = reactEventType;this.nativeEvent = nativeEvent;this.target = nativeEventTarget;this.currentTarget = null;// React根据不同事件类型写了对应的属性接口,这里基于接口将原生事件上的属性clone到构造函数中for (var _propName in Interface) {... }var defaultPrevented = nativeEvent.defaultPrevented != null ? nativeEvent.defaultPrevented : nativeEvent.returnValue === false;if (defaultPrevented) {this.isDefaultPrevented = functionThatReturnsTrue;} else {this.isDefaultPrevented = functionThatReturnsFalse;}this.isPropagationStopped = functionThatReturnsFalse;return this;}_assign(SyntheticBaseEvent.prototype, {// 阻止默认事件preventDefault: function () {...},// 阻止捕获和冒泡阶段中当前事件的进一步传播stopPropagation: function () {...},// 合成事件不使用对象池了,这个事件是空的,没有意义,保存是为了向下兼容不报错。persist: function () {},isPersistent: functionThatReturnsTrue});return SyntheticBaseEvent;
} 

看到这里,我们基本能弄明白合成事件是个什么东西了。

React合成事件是将同类型的事件找出来,基于这个类型的事件,React通过代码定义好的类型事件的接口和原生事件创建相应的合成事件实例,并重写了preventDefaultstopPropagation方法。

这样,同类型的事件会复用同一个合成事件实例对象,节省了单独为每一个事件创建事件实例对象的开销,这就是事件的合成。

捕获和冒泡

事件派发分为两个阶段执行, 捕获阶段和冒泡阶段。

在上面事件合成中讲过,React会根据事件触发的fiber节点向上查找,将上面的同类型事件添加到队列中,这样天然就有了一个冒泡的顺序,从最底层向上冒泡。如果倒序过来遍历就是捕获的顺序。

所以,React实现冒泡和捕获就很简单了,只需要根据事件派发的阶段,判断是冒泡阶段还是捕获阶段来决定是正序遍历listeners还是倒序遍历就行了。

总结

说是讲React的合成事件,实际上讲了React的事件系统。做下总结:

React的事件系统分为几个部分:

  • 事件注册;* 事件监听;* 事件合成;* 事件派发; 事件系统流程:1.在React代码执行时,内部会自动执行事件的注册;2.第一次渲染,创建fiberRoot时,会进行事件的监听,所有的事件通过addEventListener委托在id=root的DOM元素上进行监听;3.在我们触发事件时,会进行事件合成,同类型事件复用一个合成事件类实例对象;4.最后进行事件的派发,执行我们代码中的事件回调函数;当然,由于篇幅问题,这里也是对React事件系统的一个精简剖析,可能忽略了一些地方,欢迎指正。

看完这篇文章, 我们可以弄明白下面这几个问题:

1.React事件委托在哪?
2.React合成事件是什么?
3.React合成事件是怎么实现的?
4.React是怎么实现冒泡和捕获的?
5.React合成事件是使用的原生事件吗?
6.React事件系统分为哪几个部分?

最后

整理了一套《前端大厂面试宝典》,包含了HTML、CSS、JavaScript、HTTP、TCP协议、浏览器、VUE、React、数据结构和算法,一共201道面试题,并对每个问题作出了回答和解析。

有需要的小伙伴,可以点击文末卡片领取这份文档,无偿分享

部分文档展示:



文章篇幅有限,后面的内容就不一一展示了

有需要的小伙伴,可以点下方卡片免费领取

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

相关文章:

  • 南京专业做网站的公司有哪些seo 适合哪些行业
  • 水网站源码郑州seo外包v1
  • dedecms织梦搬家公司网站模板软文营销文章范文
  • 用easyui皮肤做漂亮的网站网络网站推广优化
  • 做个企业网站需要多少钱外贸网站推广公司
  • 怎么做微信电影网站百度站长工具网站
  • 静态网站和动态网站的区别网络推广员有前途吗
  • 欧洲网站设计国外免费发产品的b2b平台
  • 东莞公司制作网站2023年新冠疫情最新消息
  • 怎么做中英文版网站2023疫情最新消息今天
  • 网站 模板下载网站策划报告
  • 对接空间站揭阳百度seo公司
  • 国内网站做国外服务器安徽百度推广怎么做
  • 网站内链设计网络营销所学课程
  • 网站建设公司正规吗seo查询爱站网
  • 武汉网站建设电话多少一键优化是什么意思
  • 平乡企业做网站俄罗斯网络攻击数量增长了80%
  • 郑州北环附近网站建设海南seo顾问服务
  • wordpress 表单附件东莞网站推广优化公司
  • wordpress微网站如何做好一个网站
  • seo教程技术整站优化百度客服24小时电话
  • 公司策划推广诊断网站seo现状的方法
  • 做心理咨询的网站搜索引擎优化的主要工作有
  • 南阳旅游网站建设新开网站
  • 网站空间商拿不回数据nba最新新闻消息
  • 网站解决方案最新的全国疫情
  • 网站开发简单优化大师怎么提交作业
  • 重庆做网站个人全国各城市疫情搜索高峰进度
  • 网站建设预算申请seo推广是做什么
  • 亚马逊网站建设案例凡科建站多少钱