公司网站建设作用,上海详细地址大全,临海建设规划信息网网站,wordpress 注册插件事件介绍
什么是事件#xff1f;
事件是在编程时系统内发生的动作或者发生的事情#xff0c;而开发者可以某种方式对事件做出回应#xff0c;而这里有几个先决条件 事件对象 给事件对象注册事件#xff0c;当事件被触发后需要做什么 事件触发
举个例子
在机场等待检票…事件介绍
什么是事件
事件是在编程时系统内发生的动作或者发生的事情而开发者可以某种方式对事件做出回应而这里有几个先决条件 事件对象 给事件对象注册事件当事件被触发后需要做什么 事件触发
举个例子
在机场等待检票听到广播后排队检票 事件对象也就是检票事件 事件注册/监听也就是我们在机场等待的时候 事件触发广播响起开始检票 事件触发之后的回调我们开始排队...
// 检票事件
var event new Event(check-ticket);
// 事件注册并编写回调
elem.addEventListener(check-ticket, function (e) { // 开始排队LiningUp()
});
// 事件触发广播开始检票
elem.dispatchEvent(event);
React合成事件基础知识
什么是合成事件
不是浏览器本身触发的事件自己创建和触发的事件。
在React中事件的写法和原生事件写法的区别 React 事件的命名采用小驼峰式camelCase而不是纯小写。 使用 JSX 语法时你需要传入一个函数作为事件处理函数而不是一个字符串。
// HTML中的写法
button onclickhandleClick()Activate Lasers
/button
// React中的写法
button onClick{handleClick}Activate Lasers
/button
为什么会有合成事件 对事件进行归类可以在事件产生的任务上包含不同的优先级 提供合成事件对象抹平浏览器的兼容性差异
合成事件机制简述
提供了一种“顶层注册事件收集统一触发”的事件机制 “顶层注册”其实是在root元素上绑定一个统一的事件处理函数 “事件收集”, 事件触发时实际上是root上的事件处理函数被执行构造合成事件对象按照冒泡或捕获的路径去组件中收集真正的事件处理函数 “统一触发”在收集过程之后对收集的事件逐一执行并共享同一个合成事件对象
React合成事件实现原理
事件注册
时机在fiber节点进入render阶段的complete阶段时名为onClick的props会被识别为事件进行处理
function setInitialDOMProperties(tag: string,domElement: Element,rootContainerElement: Element | Document,nextProps: Object,isCustomComponentTag: boolean,
): void {for (const propKey in nextProps) {if (!nextProps.hasOwnProperty(propKey)) {...} else if (registrationNameDependencies.hasOwnProperty(propKey)) {// 如果propKey属于事件类型则进行事件绑定ensureListeningTo(rootContainerElement, propKey, domElement);}}}
}
// registrationNameDependencies为合成事件名和真实事件的映射格式如下
{onChange: [change, click, focusin, focusout, input, keydown, keyup, selectionchange]onChangeCapture: [change, click, focusin, focusout, input, keydown, keyup, selectionchange]onClick: [click]
}
调用ensureListeningTo进行事件绑定
然后调用DOMPluginEventSystem.js中的addTrappedEventListener进行事件注册而监听器listener是React通过createEventListenerWrapperWithPriority创建出优先级不同的时间监听包装器
总的来说会有三种事件监听包装器 dispatchDiscreteEvent: 处理离散事件 dispatchUserBlockingUpdate处理用户阻塞事件 dispatchEvent处理连续事件
事件触发-事件监听器做了什么
负责以不同的优先级权重来触发真正的事件流程
在createEventListenerWrapperWithPriority中根据eventPriority事件优先级不同调用事件dispatchDiscreteEvent、dispatchUserBlockingUpdate、dispatchUserBlockingUpdate、dispatchEvent进行事件绑定
export function createEventListenerWrapperWithPriority(targetContainer: EventTarget,domEventName: DOMEventName,eventSystemFlags: EventSystemFlags,
): Function {const eventPriority getEventPriorityForPluginSystem(domEventName);let 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,);
}
在每一个事件绑定函数中会调用dispatchEventsForPlugins函数 合成事件放入dispatchQueue中 而dispatchQueue由两部分组成 合成事件对象 多个listeners(可以共用一个合成事件对象) 执行事件执行路径下的事件从dispatchQueue中取出事件对象events和具体执行路径listeners然后遍历执行
function dispatchEventsForPlugins(domEventName: DOMEventName,eventSystemFlags: EventSystemFlags,nativeEvent: AnyNativeEvent,targetInst: null | Fiber,targetContainer: EventTarget,
): void {const nativeEventTarget getEventTarget(nativeEvent);const dispatchQueue: DispatchQueue [];// 通过不同事件类型插件进行事件对象合成将合成事件放入事件队列中dispatchQueue中extractEvents(dispatchQueue,domEventName,targetInst,nativeEvent,nativeEventTarget,eventSystemFlags,targetContainer,);// 执行dispatchQueue中具体事件执行路径下的事件processDispatchQueue(dispatchQueue, eventSystemFlags);
}
// 通过extractEvents合成的dispatchQueue的格式如下
[{// event是合成事件对象event, // 具体的事件执行路径currentTarget、listener等信息listeners: [{currentTarget: div.counter,instance: FiberNode {tag: 5, key: null, elementType: div, type: div, stateNode: div.counter, …},listener: e {…}}{currentTarget: div.counter-parent,instance: FiberNode {tag: 5, key: null, elementType: div, type: div, stateNode: div.counter, …},listener: e {…}}] }
]
React中模拟冒泡和捕获
原理收集的事件放在dispatchQueue数组中而冒泡和捕获的区别在于执行时机和顺序那么我们只需要对数组按照不同顺序循环执行即可
function processDispatchQueueItemsInOrder(event: ReactSyntheticEvent,dispatchListeners: ArrayDispatchListener,inCapturePhase: boolean,
): void {let previousInstance;if (inCapturePhase) {// 事件捕获倒序循环for (let i dispatchListeners.length - 1; i 0; i--) {const {instance, currentTarget, listener} dispatchListeners[i];if (instance ! previousInstance event.isPropagationStopped()) {return;}// 执行事件传入event对象和currentTargetexecuteDispatch(event, listener, currentTarget);previousInstance instance;}} else {// 事件冒泡正序循环for (let i 0; i dispatchListeners.length; i) {const {instance, currentTarget, listener} dispatchListeners[i];// 如果事件对象阻止了冒泡则return掉循环过程if (instance ! previousInstance event.isPropagationStopped()) {return;}executeDispatch(event, listener, currentTarget);previousInstance instance;}}
}