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(); // 停止冒泡,防止触发父级模块 });