- 实现构造函数和 Map 存储的监听器注册表 - 实现 on() 方法:添加事件监听器并自动跟踪 - 实现 off() 方法:移除指定元素和事件的所有监听器 - 实现 clear() 方法:清除所有已注册的事件监听器 - 实现 _getKey() 私有方法:为元素和事件生成唯一标识 - 支持 passive 等事件选项配置 - 在 clear() 中添加错误处理,避免元素已移除时报错 - 导出 ArgonEventManager 类供其他模块使用 验证需求:2.5, 11.2, 11.4
258 lines
6.7 KiB
JavaScript
258 lines
6.7 KiB
JavaScript
// ==========================================================================
|
||
// Argon 主题性能优化模块
|
||
// ==========================================================================
|
||
// 本模块提供系统性的性能优化功能,包括:
|
||
// - DOM 缓存系统
|
||
// - 事件节流和防抖
|
||
// - 资源按需加载
|
||
// - 渲染优化
|
||
// - 内存管理
|
||
// - 性能监控
|
||
// ==========================================================================
|
||
|
||
/**
|
||
* 全局性能配置对象
|
||
* 包含所有性能优化相关的配置参数
|
||
*/
|
||
const ArgonPerformanceConfig = {
|
||
// 事件节流配置
|
||
throttle: {
|
||
scroll: 16, // 滚动事件节流间隔(毫秒)
|
||
resize: 16, // resize 事件节流间隔(毫秒)
|
||
mousemove: 16 // 鼠标移动事件节流间隔(毫秒)
|
||
},
|
||
|
||
// 事件防抖配置
|
||
debounce: {
|
||
resize: 150, // resize 事件防抖延迟(毫秒)
|
||
input: 300, // 输入事件防抖延迟(毫秒)
|
||
search: 500 // 搜索事件防抖延迟(毫秒)
|
||
},
|
||
|
||
// 资源加载配置
|
||
lazyLoad: {
|
||
prism: true, // 按需加载 Prism
|
||
zoomify: true, // 按需加载 Zoomify
|
||
tippy: true // 按需加载 Tippy
|
||
},
|
||
|
||
// 缓存配置
|
||
cache: {
|
||
maxSize: 100, // 最大缓存数量
|
||
ttl: 300000 // 缓存过期时间(毫秒)
|
||
},
|
||
|
||
// 性能监控配置
|
||
monitor: {
|
||
enabled: false, // 是否启用监控(默认关闭,可通过 argonConfig.debug_mode 启用)
|
||
reportInterval: 60000 // 报告间隔(毫秒)
|
||
}
|
||
};
|
||
|
||
// ==========================================================================
|
||
// DOM 缓存模块
|
||
// ==========================================================================
|
||
|
||
/**
|
||
* DOM 缓存类
|
||
* 缓存频繁访问的 DOM 元素,避免重复查询,提升性能
|
||
*
|
||
* @class ArgonDOMCache
|
||
*/
|
||
class ArgonDOMCache {
|
||
/**
|
||
* 构造函数
|
||
* 初始化缓存存储结构
|
||
*/
|
||
constructor() {
|
||
this.cache = new Map();
|
||
this.initialized = false;
|
||
}
|
||
|
||
/**
|
||
* 初始化缓存
|
||
* 缓存所有频繁访问的 DOM 元素
|
||
*
|
||
* @returns {void}
|
||
*/
|
||
init() {
|
||
this.cache.clear();
|
||
|
||
// 缓存常用元素
|
||
this.set('toolbar', document.querySelector('.navbar'));
|
||
this.set('content', document.getElementById('content'));
|
||
this.set('leftbar', document.getElementById('leftbar'));
|
||
this.set('sidebar', document.getElementById('sidebar'));
|
||
this.set('backToTopBtn', document.getElementById('fabtn_back_to_top'));
|
||
this.set('readingProgress', document.getElementById('fabtn_reading_progress'));
|
||
this.set('comments', document.getElementById('comments'));
|
||
this.set('postComment', document.getElementById('post_comment'));
|
||
|
||
this.initialized = true;
|
||
}
|
||
|
||
/**
|
||
* 获取缓存的元素
|
||
*
|
||
* @param {string} key - 元素键名
|
||
* @returns {Element|null} DOM 元素或 null(如果不存在)
|
||
*/
|
||
get(key) {
|
||
if (!this.cache.has(key)) {
|
||
return null;
|
||
}
|
||
return this.cache.get(key);
|
||
}
|
||
|
||
/**
|
||
* 设置缓存
|
||
*
|
||
* @param {string} key - 元素键名
|
||
* @param {Element|null} element - DOM 元素
|
||
* @returns {void}
|
||
*/
|
||
set(key, element) {
|
||
this.cache.set(key, element);
|
||
}
|
||
|
||
/**
|
||
* 清空缓存
|
||
* 通常在 PJAX 页面切换时调用
|
||
*
|
||
* @returns {void}
|
||
*/
|
||
clear() {
|
||
this.cache.clear();
|
||
this.initialized = false;
|
||
}
|
||
}
|
||
|
||
// ==========================================================================
|
||
// 事件管理模块
|
||
// ==========================================================================
|
||
|
||
/**
|
||
* 事件管理类
|
||
* 提供事件节流、防抖和监听器生命周期管理功能
|
||
*
|
||
* @class ArgonEventManager
|
||
*/
|
||
class ArgonEventManager {
|
||
/**
|
||
* 构造函数
|
||
* 初始化监听器注册表
|
||
*/
|
||
constructor() {
|
||
this.listeners = new Map();
|
||
}
|
||
|
||
/**
|
||
* 添加事件监听器
|
||
* 自动跟踪监听器以便后续清理
|
||
*
|
||
* @param {Element|Window|Document} element - DOM 元素、Window 或 Document 对象
|
||
* @param {string} event - 事件名称(如 'scroll', 'resize', 'click')
|
||
* @param {Function} handler - 事件处理函数
|
||
* @param {Object} options - 事件监听器选项(如 { passive: true })
|
||
* @returns {void}
|
||
*/
|
||
on(element, event, handler, options = {}) {
|
||
if (!element) return;
|
||
|
||
const key = this._getKey(element, event);
|
||
element.addEventListener(event, handler, options);
|
||
|
||
if (!this.listeners.has(key)) {
|
||
this.listeners.set(key, []);
|
||
}
|
||
this.listeners.get(key).push({ element, handler, options });
|
||
}
|
||
|
||
/**
|
||
* 移除事件监听器
|
||
* 移除指定元素上的指定事件的所有监听器
|
||
*
|
||
* @param {Element|Window|Document} element - DOM 元素、Window 或 Document 对象
|
||
* @param {string} event - 事件名称
|
||
* @returns {void}
|
||
*/
|
||
off(element, event) {
|
||
if (!element) return;
|
||
|
||
const key = this._getKey(element, event);
|
||
const handlers = this.listeners.get(key);
|
||
|
||
if (handlers) {
|
||
handlers.forEach(({ handler, options }) => {
|
||
element.removeEventListener(event, handler, options);
|
||
});
|
||
this.listeners.delete(key);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 清除所有事件监听器
|
||
* 通常在 PJAX 页面切换或组件销毁时调用
|
||
*
|
||
* @returns {void}
|
||
*/
|
||
clear() {
|
||
this.listeners.forEach((handlers, key) => {
|
||
// 从 key 中提取事件类型
|
||
const eventType = key.split('_').pop();
|
||
handlers.forEach(({ element, handler, options }) => {
|
||
if (element) {
|
||
try {
|
||
element.removeEventListener(eventType, handler, options);
|
||
} catch (e) {
|
||
// 静默失败,元素可能已被移除
|
||
}
|
||
}
|
||
});
|
||
});
|
||
this.listeners.clear();
|
||
}
|
||
|
||
/**
|
||
* 生成元素和事件的唯一键
|
||
*
|
||
* @private
|
||
* @param {Element|Window|Document} element - DOM 元素
|
||
* @param {string} event - 事件名称
|
||
* @returns {string} 唯一键
|
||
*/
|
||
_getKey(element, event) {
|
||
// 为元素生成唯一标识
|
||
if (!element._argonEventId) {
|
||
element._argonEventId = `elem_${Math.random().toString(36).substr(2, 9)}`;
|
||
}
|
||
return `${element._argonEventId}_${event}`;
|
||
}
|
||
}
|
||
|
||
// ==========================================================================
|
||
// 模块导出和初始化接口
|
||
// ==========================================================================
|
||
|
||
/**
|
||
* 性能优化模块初始化函数
|
||
* 在主题加载时调用,初始化所有优化模块
|
||
*/
|
||
function initArgonPerformance() {
|
||
// 根据调试模式设置性能监控
|
||
if (typeof argonConfig !== 'undefined' && argonConfig.debug_mode) {
|
||
ArgonPerformanceConfig.monitor.enabled = true;
|
||
}
|
||
|
||
// 初始化各个模块的代码将在后续任务中添加
|
||
console.info('Argon Performance Optimization Module Loaded');
|
||
}
|
||
|
||
// 导出配置对象和类供其他模块使用
|
||
if (typeof window !== 'undefined') {
|
||
window.ArgonPerformanceConfig = ArgonPerformanceConfig;
|
||
window.ArgonDOMCache = ArgonDOMCache;
|
||
window.ArgonEventManager = ArgonEventManager;
|
||
window.initArgonPerformance = initArgonPerformance;
|
||
}
|