SyntheticEvent

This commit is contained in:
2024-12-11 01:53:15 +08:00
parent ad3fe496ef
commit dd9f5dcaaa
5 changed files with 195 additions and 0 deletions

69
demo/test-event/index.js Normal file
View File

@@ -0,0 +1,69 @@
const root = document.getElementById('root');
// 全局事件管理对象
const eventRegistry = [];
// 注册事件方法
function delegateEvent(selector, callback) {
const newEntry = { selector, callback };
// 获取新选择器对应的元素
const newElement = document.querySelector(selector);
if (!newElement) return; // 如果选择器无效,直接返回
// 动态插入到 eventRegistry并根据包含关系排序
let inserted = false;
for (let i = 0; i < eventRegistry.length; i++) {
const existingElement = document.querySelector(eventRegistry[i].selector);
if (existingElement && existingElement.contains(newElement)) {
// 当前选择器包含新选择器,新选择器应该插在当前选择器后面
eventRegistry.splice(i + 1, 0, newEntry);
inserted = true;
break;
} else if (newElement.contains(existingElement)) {
// 新选择器包含当前选择器,新选择器应该插在当前选择器前面
eventRegistry.splice(i, 0, newEntry);
inserted = true;
break;
}
}
// 如果没有找到合适的位置,直接追加到末尾
if (!inserted) {
eventRegistry.push(newEntry);
}
}
// 为 Event 添加一个标志来记录是否已停止冒泡
(function () {
const originalStopPropagation = Event.prototype.stopPropagation;
Event.prototype.stopPropagation = function () {
this.propagationStopped = true;
originalStopPropagation.call(this); // 调用原始的 stopPropagation 方法
};
})();
// 统一事件处理函数
root.addEventListener('click', (event) => {
const target = event.target;
// 遍历排序后的注册表
for (const { selector, callback } of eventRegistry.reverse()) {
if (event.propagationStopped) break; // 停止冒泡时中断匹配
const element = document.querySelector(selector);
if (element && (element === target || element.contains(target))) {
callback(event);
}
}
});
// 示例:为 `222-child` 和 `222` 添加点击事件
delegateEvent('#root > div:nth-child(2)', (event) => {
console.log('222 被点击');
});
delegateEvent('#root > div:nth-child(2) > div', (event) => {
console.log('222-child 被点击');
event.stopPropagation(); // 停止冒泡,防止触发父级模块
});