SyntheticEvent
This commit is contained in:
69
demo/test-event/index.js
Normal file
69
demo/test-event/index.js
Normal 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(); // 停止冒泡,防止触发父级模块
|
||||
});
|
||||
Reference in New Issue
Block a user