Files
2025-06-06 14:38:34 +08:00

237 lines
6.3 KiB
JavaScript

/**
* 事件管理器
* 统一管理所有与事件相关的操作,包括DOM事件、鼠标事件等
*/
import { logger } from './logger.js';
class EventManager {
// 事件存储 - 使用Map嵌套Map来存储事件和监听器
static listeners = new Map();
// 全局鼠标位置
static mousePosition = { x: 0, y: 0 };
// 初始化状态标记
static initialized = false;
static _mouseHandler = null;
/**
* 初始化事件管理器
*/
static init() {
// 严格检查避免重复初始化
if (this.initialized) {
return true;
}
try {
// 设置全局鼠标跟踪
this.setupGlobalMouseTracking();
this.initialized = true;
logger.log("事件管理器 | 初始化完成");
return true;
} catch (error) {
logger.error(`事件管理器 | 初始化失败 | ${error.message}`);
return false;
}
}
/**
* 设置全局鼠标位置跟踪
*/
static setupGlobalMouseTracking() {
// 移除可能存在的旧监听器
if (this._mouseHandler) {
document.removeEventListener('mousemove', this._mouseHandler);
}
// 创建新的鼠标处理函数
this._mouseHandler = (e) => {
// 更新鼠标位置
this.mousePosition.x = e.clientX;
this.mousePosition.y = e.clientY;
// 触发自定义事件
this.emit('global_mouse_move', e);
};
// 添加鼠标监听
document.addEventListener('mousemove', this._mouseHandler);
}
/**
* 获取当前鼠标位置
*/
static getMousePosition() {
return { ...this.mousePosition };
}
/**
* 判断鼠标是否在元素上方
*/
static isMouseOverElement(element) {
if (!element) return false;
try {
const rect = element.getBoundingClientRect();
return (
this.mousePosition.x >= rect.left &&
this.mousePosition.x <= rect.right &&
this.mousePosition.y >= rect.top &&
this.mousePosition.y <= rect.bottom
);
} catch {
return false;
}
}
/**
* 添加事件监听器
*/
static on(eventKey, id, callback) {
// 参数验证
if (!eventKey || !id || typeof callback !== 'function') {
logger.error(`事件注册失败 | 无效参数 | 事件: ${eventKey}`);
return false;
}
// 获取或创建事件监听器集合
if (!this.listeners.has(eventKey)) {
this.listeners.set(eventKey, new Map());
}
const listeners = this.listeners.get(eventKey);
// 检查是否已存在相同ID的监听器
if (listeners.has(id)) {
return true; // 已存在,静默返回
}
// 添加新的监听器
listeners.set(id, callback);
return true;
}
/**
* 移除事件监听器
*/
static off(eventKey, id) {
// 参数验证
if (!eventKey || !id) return false;
// 检查事件和监听器是否存在
if (!this.listeners.has(eventKey)) return false;
const listeners = this.listeners.get(eventKey);
const removed = listeners.delete(id);
// 如果该事件没有监听器了,则删除整个事件
if (listeners.size === 0) {
this.listeners.delete(eventKey);
}
return removed;
}
/**
* 触发事件
*/
static emit(eventKey, ...args) {
if (!eventKey) return false;
// 检查事件是否有监听器
if (!this.listeners.has(eventKey)) return false;
const listeners = this.listeners.get(eventKey);
if (listeners.size === 0) return false;
// 执行所有监听器
for (const [id, callback] of listeners.entries()) {
try {
callback(...args);
} catch (error) {
logger.error(`事件处理错误 | 事件: ${eventKey}, ID: ${id} | 错误: ${error.message}`);
}
}
return true;
}
/**
* 添加DOM事件监听器
* 简化的辅助方法,返回用于移除监听器的函数
*/
static addDOMListener(element, event, handler, options = false) {
if (!element || !event || typeof handler !== 'function') {
return () => { };
}
element.addEventListener(event, handler, options);
return () => {
element.removeEventListener(event, handler, options);
};
}
/**
* 创建防抖函数
* 限制函数调用频率
*/
static debounce(func, wait = 100) {
let timeout;
return function (...args) {
clearTimeout(timeout);
timeout = setTimeout(() => func.apply(this, args), wait);
};
}
/**
* 注册元素的悬停事件(简化版本)
*/
static registerHoverEvents(element, id, onEnter, onLeave) {
if (!element) return () => { };
const enterHandler = () => onEnter && onEnter();
const leaveHandler = () => onLeave && onLeave();
element.addEventListener('mouseenter', enterHandler);
element.addEventListener('mouseleave', leaveHandler);
return () => {
element.removeEventListener('mouseenter', enterHandler);
element.removeEventListener('mouseleave', leaveHandler);
};
}
/**
* 清理事件管理器
*/
static cleanup(keepGlobalEvents = true) {
if (keepGlobalEvents) {
// 保留全局事件,清理其他事件
const globalEvents = ['global_mouse_move'];
for (const [eventKey, listeners] of this.listeners.entries()) {
if (!globalEvents.includes(eventKey)) {
this.listeners.delete(eventKey);
}
}
} else {
// 清理所有事件和监听器
this.listeners.clear();
// 移除全局鼠标监听
if (this._mouseHandler) {
document.removeEventListener('mousemove', this._mouseHandler);
this._mouseHandler = null;
}
// 重置状态
this.initialized = false;
}
}
}
export { EventManager };