2 .以一个click事件为例.click事件属于离散事件,优先级较低
3 .离散事件的监听并不会立即执行,而是以一定的优先级进行调度
4 .Fiber 允许一个任务在页面渲染比较繁忙的时候不执行更新,等待浏览器空闲的时候执行。但是这个延后是有限制的,比如对于同步任务,过期时间就是 -1,表示同步任务需要立即执行。对于优先级是 UserBlockingPriority,过期时间是 250,也就是允许最长延期 250ms 执行。这个优先级还是比较高的
5 .事件分为三类:分别是离散事件,用户阻塞事件,连续事件.连续事件不会经过调度,而是直接执行
6 .离散事件和用户阻塞事件执行调度的优先级相同,不同点在于离散事件执行调度q会把之前未执行的事件以同步的方式执行掉.
7 .一个nativeEvent在进入调度,也就是开始执行回调的时候,首先会根据nativeEvent获得事件发生时的目标节点,以及对应的fiber对象.然后根据这些信息去React的事件插件种获得该原生事件对应的sytheticEvent合成事件.一个原生事件可以对应多个合成事件
8 .多个合成事件一次执行dispatchlisteners中存储的监听方法,在每个监听事件中判断事件是否停止传播
9 .事件执行完毕之后,判断用户是否设置额事件持久化,如果没有,重置事件中的属性,放入事件缓存池保存
如上图所示:
在JavaScript中,事件的触发实质上是要经过三个阶段:事件捕获、目标对象本身的事件处理和事件冒泡。
事件委托的实质就是将子元素事件的处理委托给父级元素处理。把事件监听器添加到它们的父元素上。事件监听器会分析从子元素冒泡上来的事件,找到它是哪个子元素的事件。
举个栗子:如果我们有一个列表,列表之中有大量的列表项,我们需要在点击列表项的时候响应一个事件
事件委托优点 :
不适用的情况: 比如 focus、blur 之类的事件本身没有事件冒泡机制,所以无法委托; mousemove、mouseout这样的事件,虽然有事件冒泡,但是只能不断通过位置去计算定位,对性能消耗高,因此也是不适合于事件委托。
在 React事件介绍 中介绍了合成事件对象以及为什么提供合成事件对象,主要原因是因为 React 想实现一个全浏览器的框架, 为了实现这种目标就需要提供全浏览器一致性的事件系统,以此抹平不同浏览器的差异。
合成事件对象很有意思,一开始听名字会觉得很奇怪,看到英文名更奇怪 SyntheticEvent , 实际上合成事件的意思就是使用原生事件合成一个 React 事件, 例如使用原生 click 事件合成了 onClick 事件,使用原生 mouseout 事件合成了 onMouseLeave 事件,原生事件和合成事件类型大部分都是一一对应,只有涉及到兼容性问题时我们才需要使用不对应的事件合成。
合成事件是浏览器的原生事件的跨浏览器包装器。除兼容所有浏览器外,它还拥有和浏览器原生事件相同的接口,包括 stopPropagation() 和 preventDefault() 。
当我们在组件上设置事件处理器时,React并不会在该DOM元素上直接绑定事件处理器. React内部自定义了一套事件系统,在这个系统上统一进行事件订阅和分发。
具体来讲,React利用事件委托机制在Document上统一监听DOM事件,再根据触发的target将事件分发到具体的组件实例。另外上面e是一个合成事件对象(SyntheticEvent), 而不是原始的DOM事件对象。
React事件系统实现可以分为两个阶段:事件注册、事件触发
ReactBrowserEventEmitter作为事件注册入口,担负着事件注册和事件触发。注册事件的回调函数由EventPluginHub来统一管理,根据事件的类型(type)和组件标识(_rootNodeID)为key唯一标识事件并进行存储。
其大致流程如下:
简单点的解释为:
React不会将事件处理函数直接绑定到真实的节点上,而是把所有的事件绑定到结构的最外层,使用一个统一的事件监听器。这个监听器维持了一个映射,保存所有组件内部的事件监听和处理函数。当事件发生时,首先被这个统一的事件监听器处理,然后在映射里找到真正的事件处理函数并调用。
需要注意的是
关于合成事件
合成事件官方文档: https://react.html.cn/docs/events.html
合成事件作用
React事件和原生事件主要区别有:
合成事件优点:
站在巨人的肩膀上(参考资料)
dom事件
React事件机制和未来 这个文章写得好!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)