优化结果
This commit is contained in:
313
InfoGenie-frontend/public/60sapi/热搜榜单/懂车帝热搜/app.js
Normal file
313
InfoGenie-frontend/public/60sapi/热搜榜单/懂车帝热搜/app.js
Normal file
@@ -0,0 +1,313 @@
|
||||
/**
|
||||
* 懂车帝热搜应用主程序
|
||||
* 整合API和UI模块,管理应用生命周期
|
||||
*/
|
||||
class CarHotTopicsApp {
|
||||
constructor() {
|
||||
this.api = null;
|
||||
this.ui = null;
|
||||
this.autoRefreshInterval = null;
|
||||
this.autoRefreshDelay = 5 * 60 * 1000; // 5分钟自动刷新
|
||||
this.isInitialized = false;
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化应用
|
||||
*/
|
||||
async init() {
|
||||
try {
|
||||
console.log('[App] 开始初始化懂车帝热搜应用...');
|
||||
|
||||
// 等待DOM加载完成
|
||||
if (document.readyState === 'loading') {
|
||||
await new Promise(resolve => {
|
||||
document.addEventListener('DOMContentLoaded', resolve);
|
||||
});
|
||||
}
|
||||
|
||||
// 检查必需的类是否存在
|
||||
if (!window.CarHotTopicsAPI || !window.UIManager) {
|
||||
throw new Error('缺少必需的模块:CarHotTopicsAPI 或 UIManager');
|
||||
}
|
||||
|
||||
// 初始化模块
|
||||
this.api = new window.CarHotTopicsAPI();
|
||||
this.ui = new window.UIManager();
|
||||
|
||||
// 检查必需的DOM元素
|
||||
this.checkRequiredElements();
|
||||
|
||||
// 绑定事件
|
||||
this.bindEvents();
|
||||
|
||||
// 首次加载数据
|
||||
await this.loadData();
|
||||
|
||||
// 设置自动刷新
|
||||
this.setupAutoRefresh();
|
||||
|
||||
// 设置页面可见性监听
|
||||
this.setupVisibilityListener();
|
||||
|
||||
this.isInitialized = true;
|
||||
console.log('[App] 应用初始化完成');
|
||||
|
||||
} catch (error) {
|
||||
console.error('[App] 初始化失败:', error);
|
||||
this.handleInitError(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查必需的DOM元素
|
||||
*/
|
||||
checkRequiredElements() {
|
||||
const requiredIds = ['loading', 'error', 'hotList', 'topicsContainer', 'refreshBtn'];
|
||||
const missingElements = requiredIds.filter(id => !document.getElementById(id));
|
||||
|
||||
if (missingElements.length > 0) {
|
||||
throw new Error(`缺少必需的DOM元素: ${missingElements.join(', ')}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定事件监听器
|
||||
*/
|
||||
bindEvents() {
|
||||
// 监听UI触发的刷新事件
|
||||
document.addEventListener('refreshData', () => {
|
||||
this.handleManualRefresh();
|
||||
});
|
||||
|
||||
// 监听网络状态变化
|
||||
window.addEventListener('online', () => {
|
||||
console.log('[App] 网络已连接,尝试刷新数据');
|
||||
this.ui.showToast('网络已连接');
|
||||
this.loadData();
|
||||
});
|
||||
|
||||
window.addEventListener('offline', () => {
|
||||
console.log('[App] 网络已断开');
|
||||
this.ui.showToast('网络连接已断开');
|
||||
});
|
||||
|
||||
// 监听页面错误
|
||||
window.addEventListener('error', (event) => {
|
||||
console.error('[App] 页面错误:', event.error);
|
||||
});
|
||||
|
||||
// 监听未处理的Promise拒绝
|
||||
window.addEventListener('unhandledrejection', (event) => {
|
||||
console.error('[App] 未处理的Promise拒绝:', event.reason);
|
||||
event.preventDefault();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 加载热搜数据
|
||||
* @param {boolean} showLoading - 是否显示加载状态
|
||||
*/
|
||||
async loadData(showLoading = true) {
|
||||
try {
|
||||
if (showLoading) {
|
||||
this.ui.showLoading();
|
||||
}
|
||||
|
||||
console.log('[App] 开始加载热搜数据...');
|
||||
const data = await this.api.fetchHotTopics();
|
||||
|
||||
console.log('[App] 数据加载成功:', data);
|
||||
this.ui.showHotList(data);
|
||||
|
||||
// 重置自动刷新计时器
|
||||
this.resetAutoRefresh();
|
||||
|
||||
} catch (error) {
|
||||
console.error('[App] 数据加载失败:', error);
|
||||
this.ui.showError(error.message);
|
||||
|
||||
// 如果是网络错误,延迟重试
|
||||
if (this.isNetworkError(error)) {
|
||||
setTimeout(() => {
|
||||
if (navigator.onLine) {
|
||||
this.loadData(false);
|
||||
}
|
||||
}, 30000); // 30秒后重试
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理手动刷新
|
||||
*/
|
||||
async handleManualRefresh() {
|
||||
console.log('[App] 手动刷新数据');
|
||||
await this.loadData();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置自动刷新
|
||||
*/
|
||||
setupAutoRefresh() {
|
||||
if (this.autoRefreshInterval) {
|
||||
clearInterval(this.autoRefreshInterval);
|
||||
}
|
||||
|
||||
this.autoRefreshInterval = setInterval(() => {
|
||||
if (document.visibilityState === 'visible' && navigator.onLine) {
|
||||
console.log('[App] 自动刷新数据');
|
||||
this.loadData(false);
|
||||
}
|
||||
}, this.autoRefreshDelay);
|
||||
|
||||
console.log(`[App] 自动刷新已设置,间隔: ${this.autoRefreshDelay / 1000}秒`);
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置自动刷新计时器
|
||||
*/
|
||||
resetAutoRefresh() {
|
||||
this.setupAutoRefresh();
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置页面可见性监听
|
||||
*/
|
||||
setupVisibilityListener() {
|
||||
document.addEventListener('visibilitychange', () => {
|
||||
if (document.visibilityState === 'visible') {
|
||||
console.log('[App] 页面变为可见');
|
||||
|
||||
// 检查数据是否需要更新
|
||||
const currentData = this.ui.getCurrentData();
|
||||
if (currentData) {
|
||||
const lastUpdate = new Date(currentData.updateTime);
|
||||
const now = new Date();
|
||||
const timeDiff = now - lastUpdate;
|
||||
|
||||
// 如果数据超过3分钟,自动刷新
|
||||
if (timeDiff > 3 * 60 * 1000) {
|
||||
console.log('[App] 数据已过期,自动刷新');
|
||||
this.loadData(false);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
console.log('[App] 页面变为隐藏');
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否为网络错误
|
||||
* @param {Error} error - 错误对象
|
||||
* @returns {boolean} 是否为网络错误
|
||||
*/
|
||||
isNetworkError(error) {
|
||||
const networkErrorMessages = [
|
||||
'fetch',
|
||||
'network',
|
||||
'timeout',
|
||||
'connection',
|
||||
'offline'
|
||||
];
|
||||
|
||||
return networkErrorMessages.some(msg =>
|
||||
error.message.toLowerCase().includes(msg)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理初始化错误
|
||||
* @param {Error} error - 错误对象
|
||||
*/
|
||||
handleInitError(error) {
|
||||
// 显示基本错误信息
|
||||
const errorContainer = document.getElementById('error');
|
||||
if (errorContainer) {
|
||||
errorContainer.style.display = 'flex';
|
||||
const errorMessage = errorContainer.querySelector('.error-message');
|
||||
if (errorMessage) {
|
||||
errorMessage.textContent = `初始化失败: ${error.message}`;
|
||||
}
|
||||
}
|
||||
|
||||
// 隐藏加载状态
|
||||
const loadingContainer = document.getElementById('loading');
|
||||
if (loadingContainer) {
|
||||
loadingContainer.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取应用状态
|
||||
* @returns {Object} 应用状态信息
|
||||
*/
|
||||
getStatus() {
|
||||
return {
|
||||
isInitialized: this.isInitialized,
|
||||
hasData: !!this.ui?.getCurrentData(),
|
||||
autoRefreshEnabled: !!this.autoRefreshInterval,
|
||||
isOnline: navigator.onLine,
|
||||
isVisible: document.visibilityState === 'visible'
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁应用
|
||||
*/
|
||||
destroy() {
|
||||
console.log('[App] 销毁应用');
|
||||
|
||||
if (this.autoRefreshInterval) {
|
||||
clearInterval(this.autoRefreshInterval);
|
||||
this.autoRefreshInterval = null;
|
||||
}
|
||||
|
||||
if (this.ui) {
|
||||
this.ui.clearData();
|
||||
}
|
||||
|
||||
this.isInitialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
// 全局错误处理
|
||||
window.addEventListener('error', (event) => {
|
||||
console.error('[Global] JavaScript错误:', {
|
||||
message: event.message,
|
||||
filename: event.filename,
|
||||
lineno: event.lineno,
|
||||
colno: event.colno,
|
||||
error: event.error
|
||||
});
|
||||
});
|
||||
|
||||
window.addEventListener('unhandledrejection', (event) => {
|
||||
console.error('[Global] 未处理的Promise拒绝:', event.reason);
|
||||
});
|
||||
|
||||
// 应用启动
|
||||
let app;
|
||||
|
||||
// 确保在DOM加载完成后启动应用
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', () => {
|
||||
app = new CarHotTopicsApp();
|
||||
});
|
||||
} else {
|
||||
app = new CarHotTopicsApp();
|
||||
}
|
||||
|
||||
// 导出应用实例(用于调试)
|
||||
window.CarHotTopicsApp = CarHotTopicsApp;
|
||||
window.app = app;
|
||||
|
||||
// 调试信息
|
||||
console.log('[App] 懂车帝热搜应用脚本已加载');
|
||||
console.log('[Debug] 可用的全局对象:', {
|
||||
CarHotTopicsAPI: !!window.CarHotTopicsAPI,
|
||||
UIManager: !!window.UIManager,
|
||||
CarHotTopicsApp: !!window.CarHotTopicsApp
|
||||
});
|
||||
Reference in New Issue
Block a user