04.注册监听事件
packages/react-dom-bindings/src/events/DOMPluginEventSystem.js
diff
import { allNativeEvents } from './EventRegistry';
import * as SimpleEventPlugin from './plugins/SimpleEventPlugin';
+import { IS_CAPTURE_PHASE } from './EventSystemFlags';
+import { createEventListenerWrapperWithPriority } from './ReactDOMEventListener';
+import {
+ addEventCaptureListener,
+ addEventBubbleListener
+} from './EventListener';
SimpleEventPlugin.registerEvents();
const listeningMarker = `_reactListening` + Math.random().toString(36).slice(2);
+/**
+ * 监听所有支持的事件
+ * @param {Element} rootContainerElement 根容器元素
+ */
export function listenToAllSupportedEvents(rootContainerElement) {
+ // 如果此元素尚未标记为已监听,则监听所有原生事件
+ if (!rootContainerElement[listeningMarker]) {
+ rootContainerElement[listeningMarker] = true;
+ allNativeEvents.forEach((domEventName) => {
+ listenToNativeEvent(domEventName, true, rootContainerElement);
+ listenToNativeEvent(domEventName, false, rootContainerElement);
+ });
+ }
}
+/**
+ * 监听原生事件
+ * @param {string} domEventName DOM 事件名称
+ * @param {boolean} isCapturePhaseListener 是否在捕获阶段监听
+ * @param {Element} target 目标元素
+ */
+export function listenToNativeEvent(domEventName, isCapturePhaseListener, target) {
+ let eventSystemFlags = 0;
+ // 如果在捕获阶段监听,设置事件系统标记
+ if (isCapturePhaseListener) {
+ eventSystemFlags |= IS_CAPTURE_PHASE;
+ }
+ addTrappedEventListener(target, domEventName, eventSystemFlags, isCapturePhaseListener);
+}
+/**
+ * 添加受限制的事件监听器
+ * @param {Element} targetContainer 目标容器元素
+ * @param {string} domEventName DOM 事件名称
+ * @param {number} eventSystemFlags 事件系统标记
+ * @param {boolean} isCapturePhaseListener 是否在捕获阶段监听
+ */
+function addTrappedEventListener(
+ targetContainer, domEventName, eventSystemFlags, isCapturePhaseListener
+) {
+ // 创建带有优先级的事件监听器
+ const listener = createEventListenerWrapperWithPriority(targetContainer, domEventName, eventSystemFlags);
+ // 根据监听阶段选择合适的添加监听函数
+ if (isCapturePhaseListener) {
+ addEventCaptureListener(targetContainer, domEventName, listener);
+ } else {
+ addEventBubbleListener(targetContainer, domEventName, listener);
+ }
+}packages/react-dom-bindings/src/events/EventListener.js
js
/**
* 在目标元素上添加捕获阶段的事件监听器
*
* @param {EventTarget} target - 目标元素,我们想要在上面添加监听器的元素
* @param {string} eventType - 事件类型,我们想要监听的事件的名称
* @param {Function} listener - 监听器函数,当事件发生时将调用的函数
*
* @returns {Function} 返回添加的监听器函数
*/
export function addEventCaptureListener(target, eventType, listener) {
// 调用目标元素的 addEventListener 方法,添加捕获阶段的事件监听器
target.addEventListener(eventType, listener, true);
// 返回添加的监听器函数
return listener;
}
/**
* 在目标元素上添加冒泡阶段的事件监听器
*
* @param {EventTarget} target - 目标元素,我们想要在上面添加监听器的元素
* @param {string} eventType - 事件类型,我们想要监听的事件的名称
* @param {Function} listener - 监听器函数,当事件发生时将调用的函数
*
* @returns {Function} 返回添加的监听器函数
*/
export function addEventBubbleListener(target, eventType, listener) {
// 调用目标元素的 addEventListener 方法,添加冒泡阶段的事件监听器
target.addEventListener(eventType, listener, false);
// 返回添加的监听器函数
return listener;
}packages/react-dom-bindings/src/events/ReactDOMEventListener.js
js
/**
* 创建一个具有优先级的事件监听器包装器。
*
* @param {HTMLElement} targetContainer - 目标容器,通常是一个HTML元素。
* @param {string} domEventName - DOM事件名称。
* @param {number} eventSystemFlags - 事件系统标志,用于表示事件在哪个阶段(冒泡/捕获)。
* @returns {function} - 绑定了特定参数的事件调度函数。
*/
export function createEventListenerWrapperWithPriority(
targetContainer,
domEventName,
eventSystemFlags
) {
const listenerWrapper = dispatchDiscreteEvent;
return listenerWrapper.bind(null, domEventName, eventSystemFlags, targetContainer);
}
/**
* 调度离散事件。
*
* @param {string} domEventName - DOM事件名称。
* @param {number} eventSystemFlags - 事件系统标志,用于表示事件在哪个阶段(冒泡/捕获)。
* @param {HTMLElement} container - 目标容器,通常是一个HTML元素。
* @param {Event} nativeEvent - 原生的浏览器事件对象。
*/
function dispatchDiscreteEvent(domEventName, eventSystemFlags, container, nativeEvent) {
}