// UI相关函数 function toggleSettings(e) { // 阻止事件冒泡,防止触发document的点击事件 e && e.stopPropagation(); const panel = document.getElementById('settingsPanel'); panel.classList.toggle('show'); } // 改进的Toast显示函数 - 支持队列显示多个Toast const toastQueue = []; let isShowingToast = false; function showToast(message, type = 'error') { // 将新的toast添加到队列 toastQueue.push({ message, type }); // 如果当前没有显示中的toast,则开始显示 if (!isShowingToast) { showNextToast(); } } function showNextToast() { if (toastQueue.length === 0) { isShowingToast = false; return; } isShowingToast = true; const { message, type } = toastQueue.shift(); const toast = document.getElementById('toast'); const toastMessage = document.getElementById('toastMessage'); const bgColors = { 'error': 'bg-red-500', 'success': 'bg-green-500', 'info': 'bg-blue-500', 'warning': 'bg-yellow-500' }; const bgColor = bgColors[type] || bgColors.error; toast.className = `fixed top-4 left-1/2 -translate-x-1/2 px-6 py-3 rounded-lg shadow-lg transform transition-all duration-300 ${bgColor} text-white`; toastMessage.textContent = message; // 显示提示 toast.style.opacity = '1'; toast.style.transform = 'translateX(-50%) translateY(0)'; // 3秒后自动隐藏 setTimeout(() => { toast.style.opacity = '0'; toast.style.transform = 'translateX(-50%) translateY(-100%)'; // 等待动画完成后显示下一个toast setTimeout(() => { showNextToast(); }, 300); }, 3000); } // 添加显示/隐藏 loading 的函数 let loadingTimeoutId = null; function showLoading(message = '加载中...') { // 清除任何现有的超时 if (loadingTimeoutId) { clearTimeout(loadingTimeoutId); } const loading = document.getElementById('loading'); const messageEl = loading.querySelector('p'); messageEl.textContent = message; loading.style.display = 'flex'; // 设置30秒后自动关闭loading,防止无限loading loadingTimeoutId = setTimeout(() => { hideLoading(); showToast('操作超时,请稍后重试', 'warning'); }, 30000); } function hideLoading() { // 清除超时 if (loadingTimeoutId) { clearTimeout(loadingTimeoutId); loadingTimeoutId = null; } const loading = document.getElementById('loading'); loading.style.display = 'none'; } function updateSiteStatus(isAvailable) { const statusEl = document.getElementById('siteStatus'); if (isAvailable) { statusEl.innerHTML = ' 可用'; } else { statusEl.innerHTML = ' 不可用'; } } function closeModal() { document.getElementById('modal').classList.add('hidden'); // 清除 iframe 内容 document.getElementById('modalContent').innerHTML = ''; } // 获取搜索历史的增强版本 - 支持新旧格式 function getSearchHistory() { try { const data = localStorage.getItem(SEARCH_HISTORY_KEY); if (!data) return []; const parsed = JSON.parse(data); // 检查是否是数组 if (!Array.isArray(parsed)) return []; // 支持旧格式(字符串数组)和新格式(对象数组) return parsed.map(item => { if (typeof item === 'string') { return { text: item, timestamp: 0 }; } return item; }).filter(item => item && item.text); } catch (e) { console.error('获取搜索历史出错:', e); return []; } } // 保存搜索历史的增强版本 - 添加时间戳和最大数量限制,现在缓存2个月 function saveSearchHistory(query) { if (!query || !query.trim()) return; // 清理输入,防止XSS query = query.trim().substring(0, 50).replace(//g, '>'); let history = getSearchHistory(); // 获取当前时间 const now = Date.now(); // 过滤掉超过2个月的记录(约60天,60*24*60*60*1000 = 5184000000毫秒) history = history.filter(item => typeof item === 'object' && item.timestamp && (now - item.timestamp < 5184000000) ); // 删除已存在的相同项 history = history.filter(item => typeof item === 'object' ? item.text !== query : item !== query ); // 新项添加到开头,包含时间戳 history.unshift({ text: query, timestamp: now }); // 限制历史记录数量 if (history.length > MAX_HISTORY_ITEMS) { history = history.slice(0, MAX_HISTORY_ITEMS); } try { localStorage.setItem(SEARCH_HISTORY_KEY, JSON.stringify(history)); } catch (e) { console.error('保存搜索历史失败:', e); // 如果存储失败(可能是localStorage已满),尝试清理旧数据 try { localStorage.removeItem(SEARCH_HISTORY_KEY); localStorage.setItem(SEARCH_HISTORY_KEY, JSON.stringify(history.slice(0, 3))); } catch (e2) { console.error('再次保存搜索历史失败:', e2); } } renderSearchHistory(); } // 渲染最近搜索历史的增强版本 function renderSearchHistory() { const historyContainer = document.getElementById('recentSearches'); if (!historyContainer) return; const history = getSearchHistory(); if (history.length === 0) { historyContainer.innerHTML = ''; return; } // 创建一个包含标题和清除按钮的行 historyContainer.innerHTML = `
最近搜索:
`; history.forEach(item => { const tag = document.createElement('button'); tag.className = 'search-tag'; tag.textContent = item.text; // 添加时间提示(如果有时间戳) if (item.timestamp) { const date = new Date(item.timestamp); tag.title = `搜索于: ${date.toLocaleString()}`; } tag.onclick = function() { document.getElementById('searchInput').value = item.text; search(); }; historyContainer.appendChild(tag); }); } // 增加清除搜索历史功能 function clearSearchHistory() { try { localStorage.removeItem(SEARCH_HISTORY_KEY); renderSearchHistory(); showToast('搜索历史已清除', 'success'); } catch (e) { console.error('清除搜索历史失败:', e); showToast('清除搜索历史失败', 'error'); } }