feat(sidepanel): 实现基于组件的架构并优化路由管理

- 引入 BaseComponent 基类统一管理事件、定时器和脚本加载
- 重构 timestamp 模块为继承自 BaseComponent 的类组件
- 新增 ScriptManager 工具类用于动态加载和卸载脚本
- 修改路由配置支持按需加载页面对应的 JS 模块
- 路由切换时自动销毁旧组件实例以防止内存泄漏
- 更新文件引用路径适配新的目录结构
- 修复 rollup 配置中的语法问题及端口配置
- 移除无用的日志输出和冗余代码提升性能
This commit is contained in:
雨霖铃
2025-12-12 00:01:00 +08:00
parent 4a76561a85
commit aaefc9c3fc
12 changed files with 281 additions and 245 deletions
+76
View File
@@ -0,0 +1,76 @@
/**
* DOM工具类函数
*/
/**
* 为元素添加事件监听器
* @param {string} id - 元素ID
* @param {string} event - 事件类型
* @param {Function} handler - 事件处理函数
*/
export function addEventListenerById(id, event, handler) {
const ele = document.getElementById(id);
if (ele) {
window.eventManager.add(ele, event, handler);
}
}
/**
* 判断元素是否包含指定类名
* @param {*} elem
* @param {*} cls
* @returns
*/
export function hasClass(elem, cls) {
cls = cls || '';
// 检测类名是否为''
if (cls.replace(/\s/g, '').length === 0) return false;
// 检测elem类名是否包含cls指定类名
return new RegExp(' ' + cls + ' ').test(' ' + elem.className + ' ');
}
/**
* 为元素添加类名
* @param {*} elem
* @param {*} cls
*/
export function addClass(elem, cls) {
if (!elem || !cls) return;
// 统一空白字符(避免 \n \t 等导致匹配问题)
let current = elem.className.replace(/[\t\r\n]/g, ' ').trim();
// 已存在则忽略
const classes = current.split(/\s+/);
if (classes.includes(cls)) return;
// 添加并规整
classes.push(cls);
elem.className = classes.join(' ').trim();
}
/**
* 为元素删除类名
* @param {*} elem
* @param {*} cls
*/
export function removeClass(elem, cls) {
if (!elem || !cls) return;
// 使用 classList 优先(更安全)
if (elem.classList) {
elem.classList.remove(cls);
return;
}
// 传统写法的修复版本
let klass = ' ' + elem.className.replace(/[\t\r\n]/g, ' ') + ' ';
// 持续删除目标 class
while (klass.indexOf(' ' + cls + ' ') !== -1) {
klass = klass.replace(' ' + cls + ' ', ' ');
}
// 过滤多余空格
elem.className = klass.trim().replace(/\s+/g, ' ');
}