Files
xianyan/preview_search.html
Developer f281e465bb chore: v6.6.6 版本迭代更新
主要变更:
1. 重构"国学"相关模块为"经典名句",统一命名规范
2. 重命名"阅读报告"为"使用报告",调整相关文案与配置
3. 修复iOS模拟器图片缓存兼容问题,优化图表渲染逻辑
4. 新增设备活跃状态前端兜底判断,修复在线计数异常
5. 完善登录/注册流程,新增忘记密码路由与账户编辑提示
6. 优化文件传输与字体导入逻辑,废弃过时的bytes属性使用
7. 添加Spotlight全局快捷键支持,更新隐私权限与通知配置
8. 补充数据库迁移脚本与部署文档,修复后端接口兼容问题
9. 调整部分UI交互细节,优化内存占用与应用稳定性
2026-06-07 06:56:52 +08:00

1132 lines
40 KiB
HTML
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>闲言APP — 我的页面下拉搜索 · 方案预览</title>
<style>
/* ========== 设计令牌 ========== */
:root {
--primary: #007AFF;
--primary-light: rgba(0,122,255,0.12);
--bg: #F2F2F7;
--bg-elevated: #FFFFFF;
--bg-glass: rgba(255,255,255,0.72);
--bg-overlay: rgba(0,0,0,0.32);
--text-primary: #1C1C1E;
--text-secondary: #8E8E93;
--text-hint: #C7C7CC;
--separator: rgba(60,60,67,0.12);
--radius-sm: 8px;
--radius-md: 12px;
--radius-lg: 16px;
--radius-xl: 20px;
--shadow-search: 0 20px 60px rgba(0,0,0,0.18), 0 0 0 0.5px rgba(0,0,0,0.08);
--font-family: -apple-system, 'SF Pro Display', 'SF Pro Text', 'Helvetica Neue', sans-serif;
}
/* 暗色主题 */
[data-theme="dark"] {
--primary: #0A84FF;
--primary-light: rgba(10,132,255,0.18);
--bg: #000000;
--bg-elevated: #1C1C1E;
--bg-glass: rgba(44,44,46,0.78);
--bg-overlay: rgba(0,0,0,0.52);
--text-primary: #FFFFFF;
--text-secondary: #98989D;
--text-hint: #48484A;
--separator: rgba(84,84,88,0.36);
--shadow-search: 0 20px 60px rgba(0,0,0,0.4), 0 0 0 0.5px rgba(255,255,255,0.06);
}
* { margin: 0; padding: 0; box-sizing: border-box; }
body {
font-family: var(--font-family);
background: var(--bg);
color: var(--text-primary);
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
transition: background 0.3s, color 0.3s;
}
/* ========== 顶部工具栏 ========== */
.toolbar {
width: 100%;
padding: 16px 24px;
display: flex;
align-items: center;
justify-content: space-between;
background: var(--bg-elevated);
border-bottom: 1px solid var(--separator);
position: sticky;
top: 0;
z-index: 100;
backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px);
}
.toolbar h1 {
font-size: 17px;
font-weight: 600;
}
.toolbar-actions {
display: flex;
gap: 12px;
align-items: center;
}
.theme-toggle {
padding: 6px 14px;
border-radius: 999px;
border: 1px solid var(--separator);
background: var(--bg);
color: var(--text-primary);
font-size: 13px;
cursor: pointer;
transition: all 0.2s;
}
.theme-toggle:hover {
background: var(--primary-light);
border-color: var(--primary);
}
/* ========== 方案说明 ========== */
.description {
max-width: 720px;
width: 100%;
padding: 24px;
}
.description h2 {
font-size: 22px;
font-weight: 700;
margin-bottom: 12px;
}
.description p {
font-size: 15px;
color: var(--text-secondary);
line-height: 1.6;
margin-bottom: 8px;
}
.feature-list {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
gap: 12px;
margin: 16px 0;
}
.feature-item {
padding: 12px 16px;
background: var(--bg-elevated);
border-radius: var(--radius-md);
border: 1px solid var(--separator);
font-size: 14px;
display: flex;
align-items: center;
gap: 8px;
}
.feature-icon {
width: 28px;
height: 28px;
border-radius: 6px;
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
flex-shrink: 0;
}
/* ========== 手机模拟器 ========== */
.phone-container {
display: flex;
gap: 40px;
padding: 24px;
flex-wrap: wrap;
justify-content: center;
}
.phone-wrapper {
display: flex;
flex-direction: column;
align-items: center;
gap: 12px;
}
.phone-label {
font-size: 14px;
font-weight: 600;
color: var(--text-secondary);
}
.phone {
width: 375px;
height: 740px;
background: var(--bg);
border-radius: 44px;
border: 3px solid var(--separator);
overflow: hidden;
position: relative;
box-shadow: 0 8px 32px rgba(0,0,0,0.12);
}
/* ========== Profile 页面内容 ========== */
.profile-page {
width: 100%;
height: 100%;
overflow-y: auto;
position: relative;
}
.profile-header {
padding: 60px 20px 16px;
display: flex;
align-items: center;
gap: 8px;
}
.profile-header-icon {
width: 28px;
height: 28px;
background: var(--primary-light);
border-radius: 50%;
display: flex;
align-items: center;
justify-content: center;
color: var(--primary);
font-size: 14px;
}
.profile-header h1 {
font-size: 28px;
font-weight: 700;
}
.profile-header-actions {
margin-left: auto;
display: flex;
gap: 8px;
}
.header-btn {
width: 32px;
height: 32px;
border-radius: 50%;
background: var(--bg-elevated);
border: 1px solid var(--separator);
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
font-size: 14px;
transition: all 0.2s;
}
.header-btn:hover {
background: var(--primary-light);
border-color: var(--primary);
}
.header-btn.search-btn {
background: var(--primary-light);
border-color: transparent;
color: var(--primary);
}
/* 用户卡片 */
.user-card {
margin: 0 16px 12px;
padding: 16px;
background: var(--bg-elevated);
border-radius: var(--radius-lg);
display: flex;
align-items: center;
gap: 12px;
}
.avatar {
width: 52px;
height: 52px;
border-radius: 50%;
background: linear-gradient(135deg, var(--primary), #5856D6);
display: flex;
align-items: center;
justify-content: center;
color: white;
font-size: 22px;
font-weight: 600;
}
.user-info { flex: 1; }
.user-name { font-size: 17px; font-weight: 600; }
.user-desc { font-size: 13px; color: var(--text-secondary); margin-top: 2px; }
/* 设置组 */
.settings-group {
margin: 0 16px 12px;
background: var(--bg-elevated);
border-radius: var(--radius-lg);
overflow: hidden;
}
.settings-item {
padding: 12px 16px;
display: flex;
align-items: center;
gap: 12px;
border-bottom: 0.5px solid var(--separator);
cursor: pointer;
transition: background 0.15s;
}
.settings-item:last-child { border-bottom: none; }
.settings-item:hover { background: var(--primary-light); }
.settings-icon {
width: 30px;
height: 30px;
border-radius: 7px;
display: flex;
align-items: center;
justify-content: center;
font-size: 15px;
color: white;
flex-shrink: 0;
}
.settings-label { flex: 1; font-size: 15px; }
.settings-chevron { color: var(--text-hint); font-size: 13px; }
/* ========== 搜索浮层 ========== */
.search-overlay {
position: absolute;
inset: 0;
background: var(--bg-overlay);
backdrop-filter: blur(30px);
-webkit-backdrop-filter: blur(30px);
z-index: 50;
display: none;
flex-direction: column;
align-items: center;
padding-top: 80px;
animation: fadeIn 0.2s ease-out;
}
.search-overlay.active { display: flex; }
@keyframes fadeIn {
from { opacity: 0; }
to { opacity: 1; }
}
@keyframes slideDown {
from { opacity: 0; transform: translateY(-16px) scale(0.98); }
to { opacity: 1; transform: translateY(0) scale(1); }
}
.search-container {
width: 340px;
background: var(--bg-glass);
backdrop-filter: saturate(180%) blur(40px);
-webkit-backdrop-filter: saturate(180%) blur(40px);
border-radius: var(--radius-xl);
box-shadow: var(--shadow-search);
overflow: hidden;
animation: slideDown 0.25s cubic-bezier(0.16, 1, 0.3, 1);
max-height: 560px;
display: flex;
flex-direction: column;
}
/* 搜索栏 */
.search-bar {
padding: 12px 16px;
display: flex;
align-items: center;
gap: 10px;
border-bottom: 0.5px solid var(--separator);
}
.search-icon {
color: var(--text-secondary);
font-size: 16px;
flex-shrink: 0;
}
.search-input {
flex: 1;
border: none;
outline: none;
background: transparent;
font-size: 17px;
color: var(--text-primary);
font-family: var(--font-family);
}
.search-input::placeholder {
color: var(--text-hint);
}
.search-clear {
width: 20px;
height: 20px;
border-radius: 50%;
background: var(--text-hint);
color: white;
display: none;
align-items: center;
justify-content: center;
font-size: 11px;
cursor: pointer;
flex-shrink: 0;
}
.search-clear.visible { display: flex; }
/* 搜索结果 */
.search-results {
overflow-y: auto;
flex: 1;
}
/* 分类标题 */
.result-category {
padding: 8px 16px 4px;
font-size: 12px;
font-weight: 600;
color: var(--text-secondary);
text-transform: uppercase;
letter-spacing: 0.5px;
}
/* 结果项 */
.result-item {
padding: 10px 16px;
display: flex;
align-items: center;
gap: 12px;
cursor: pointer;
transition: background 0.12s;
}
.result-item:hover, .result-item.selected {
background: var(--primary-light);
}
.result-icon {
width: 36px;
height: 36px;
border-radius: var(--radius-sm);
display: flex;
align-items: center;
justify-content: center;
font-size: 17px;
flex-shrink: 0;
}
.result-icon.page {
background: linear-gradient(135deg, #007AFF, #5856D6);
color: white;
}
.result-icon.feature {
background: linear-gradient(135deg, #34C759, #30D158);
color: white;
}
.result-icon.tool {
background: linear-gradient(135deg, #FF9500, #FF6B00);
color: white;
}
.result-icon.setting {
background: linear-gradient(135deg, #8E8E93, #636366);
color: white;
}
.result-icon.content {
background: linear-gradient(135deg, #AF52DE, #BF5AF2);
color: white;
}
.result-content { flex: 1; min-width: 0; }
.result-title {
font-size: 15px;
font-weight: 500;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.result-title mark {
background: none;
color: var(--primary);
font-weight: 700;
}
.result-subtitle {
font-size: 12px;
color: var(--text-secondary);
margin-top: 1px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.result-badge {
padding: 2px 8px;
border-radius: 999px;
font-size: 11px;
font-weight: 600;
flex-shrink: 0;
}
.result-badge.page { background: rgba(0,122,255,0.12); color: #007AFF; }
.result-badge.feature { background: rgba(52,199,89,0.12); color: #34C759; }
.result-badge.tool { background: rgba(255,149,0,0.12); color: #FF9500; }
.result-badge.setting { background: rgba(142,142,147,0.12); color: #8E8E93; }
.result-badge.content { background: rgba(175,82,222,0.12); color: #AF52DE; }
/* 快捷键提示 */
.shortcut-hint {
padding: 10px 16px;
border-top: 0.5px solid var(--separator);
display: flex;
align-items: center;
justify-content: center;
gap: 16px;
font-size: 12px;
color: var(--text-hint);
}
.kbd {
display: inline-flex;
align-items: center;
justify-content: center;
padding: 2px 6px;
background: var(--bg-elevated);
border: 1px solid var(--separator);
border-radius: 4px;
font-size: 11px;
font-family: var(--font-family);
color: var(--text-secondary);
min-width: 20px;
}
/* 空状态 */
.empty-state {
padding: 40px 16px;
text-align: center;
}
.empty-icon {
font-size: 40px;
margin-bottom: 12px;
opacity: 0.4;
}
.empty-text {
font-size: 15px;
color: var(--text-secondary);
}
.empty-hint {
font-size: 13px;
color: var(--text-hint);
margin-top: 4px;
}
/* 最近搜索标签 */
.recent-tags {
padding: 8px 16px 12px;
display: flex;
flex-wrap: wrap;
gap: 6px;
}
.recent-tag {
padding: 4px 10px;
background: var(--bg-elevated);
border: 1px solid var(--separator);
border-radius: 999px;
font-size: 13px;
color: var(--text-secondary);
cursor: pointer;
transition: all 0.15s;
}
.recent-tag:hover {
background: var(--primary-light);
border-color: var(--primary);
color: var(--primary);
}
/* ========== 方案对比 ========== */
.comparison {
max-width: 720px;
width: 100%;
padding: 0 24px 24px;
}
.comparison h3 {
font-size: 18px;
font-weight: 700;
margin: 24px 0 12px;
}
.comparison-table {
width: 100%;
border-collapse: collapse;
font-size: 14px;
}
.comparison-table th, .comparison-table td {
padding: 10px 12px;
text-align: left;
border-bottom: 1px solid var(--separator);
}
.comparison-table th {
font-weight: 600;
color: var(--text-secondary);
font-size: 12px;
text-transform: uppercase;
letter-spacing: 0.5px;
}
.comparison-table td { color: var(--text-primary); }
.check { color: #34C759; }
.cross { color: #FF3B30; }
/* ========== 交互脚本 ========== */
.click-hint {
position: absolute;
bottom: 16px;
left: 50%;
transform: translateX(-50%);
padding: 6px 14px;
background: var(--primary);
color: white;
border-radius: 999px;
font-size: 12px;
font-weight: 600;
animation: pulse 2s infinite;
z-index: 10;
pointer-events: none;
}
@keyframes pulse {
0%, 100% { opacity: 1; }
50% { opacity: 0.6; }
}
</style>
</head>
<body data-theme="light">
<!-- 工具栏 -->
<div class="toolbar">
<h1>🔍 闲言APP — 我的页面下拉搜索 · 方案预览</h1>
<div class="toolbar-actions">
<button class="theme-toggle" onclick="toggleTheme()">🌓 切换主题</button>
</div>
</div>
<!-- 方案说明 -->
<div class="description">
<h2>方案概述</h2>
<p>在「我的」页面顶部标题栏增加搜索入口,点击后弹出 macOS Spotlight 风格的搜索浮层,支持快速跳转到应用内任意页面/功能/设置。</p>
<div class="feature-list">
<div class="feature-item">
<div class="feature-icon" style="background:rgba(0,122,255,0.12);color:#007AFF;">🔍</div>
<span>实时搜索建议</span>
</div>
<div class="feature-item">
<div class="feature-icon" style="background:rgba(52,199,89,0.12);color:#34C759;">📂</div>
<span>分类结果展示</span>
</div>
<div class="feature-item">
<div class="feature-icon" style="background:rgba(255,149,0,0.12);color:#FF9500;">⌨️</div>
<span>键盘快捷键</span>
</div>
<div class="feature-item">
<div class="feature-icon" style="background:rgba(175,82,222,0.12);color:#AF52DE;">🎨</div>
<span>动态主题适配</span>
</div>
<div class="feature-item">
<div class="feature-icon" style="background:rgba(255,59,48,0.12);color:#FF3B30;">🕐</div>
<span>最近搜索记录</span>
</div>
<div class="feature-item">
<div class="feature-icon" style="background:rgba(88,86,214,0.12);color:#5856D6;">🚀</div>
<span>拼音首字母匹配</span>
</div>
</div>
</div>
<!-- 手机模拟器 -->
<div class="phone-container">
<!-- 状态1: 默认页面 -->
<div class="phone-wrapper">
<div class="phone-label">默认状态 — 搜索入口</div>
<div class="phone" id="phone-default">
<div class="profile-page">
<div class="profile-header">
<div class="profile-header-icon">👤</div>
<h1>我的</h1>
<div class="profile-header-actions">
<div class="header-btn search-btn" onclick="showSearch('default')">🔍</div>
<div class="header-btn"></div>
</div>
</div>
<div class="user-card">
<div class="avatar"></div>
<div class="user-info">
<div class="user-name">闲言用户</div>
<div class="user-desc">Lv.6 · 积分 2,580</div>
</div>
<div style="color:var(--text-hint);font-size:13px;"></div>
</div>
<div class="settings-group">
<div class="settings-item">
<div class="settings-icon" style="background:#FF3B30;">❤️</div>
<span class="settings-label">收藏</span>
<span class="settings-chevron"></span>
</div>
<div class="settings-item">
<div class="settings-icon" style="background:#007AFF;">📖</div>
<span class="settings-label">阅读历史</span>
<span class="settings-chevron"></span>
</div>
</div>
<div class="settings-group">
<div class="settings-item">
<div class="settings-icon" style="background:#5856D6;">⚙️</div>
<span class="settings-label">账号设置</span>
<span class="settings-chevron"></span>
</div>
<div class="settings-item">
<div class="settings-icon" style="background:#FF9500;">💾</div>
<span class="settings-label">数据管理</span>
<span class="settings-chevron"></span>
</div>
<div class="settings-item">
<div class="settings-icon" style="background:#34C759;">🌐</div>
<span class="settings-label">语言</span>
<span class="settings-chevron"></span>
</div>
</div>
<div class="settings-group">
<div class="settings-item">
<div class="settings-icon" style="background:#8E8E93;"></div>
<span class="settings-label">关于</span>
<span class="settings-chevron"></span>
</div>
</div>
</div>
<div class="click-hint">👆 点击搜索图标试试</div>
</div>
</div>
<!-- 状态2: 搜索浮层 - 初始 -->
<div class="phone-wrapper">
<div class="phone-label">搜索浮层 — 初始状态</div>
<div class="phone" id="phone-initial">
<div class="profile-page" style="filter:blur(2px);">
<div class="profile-header">
<div class="profile-header-icon">👤</div>
<h1>我的</h1>
</div>
<div class="user-card">
<div class="avatar"></div>
<div class="user-info">
<div class="user-name">闲言用户</div>
<div class="user-desc">Lv.6 · 积分 2,580</div>
</div>
</div>
</div>
<div class="search-overlay active" onclick="hideSearch(event, 'initial')">
<div class="search-container" onclick="event.stopPropagation()">
<div class="search-bar">
<span class="search-icon">🔍</span>
<input class="search-input" type="text" placeholder="搜索页面、功能、设置…" oninput="handleSearch(this, 'initial')" id="input-initial">
<div class="search-clear" id="clear-initial" onclick="clearSearch('initial')"></div>
</div>
<div class="search-results" id="results-initial">
<div class="result-category">最近搜索</div>
<div class="recent-tags">
<span class="recent-tag" onclick="fillSearch('initial', '天气')">天气</span>
<span class="recent-tag" onclick="fillSearch('initial', '笔记')">笔记</span>
<span class="recent-tag" onclick="fillSearch('initial', '主题')">主题</span>
<span class="recent-tag" onclick="fillSearch('initial', '番茄钟')">番茄钟</span>
<span class="recent-tag" onclick="fillSearch('initial', '签到')">签到</span>
</div>
<div class="result-category">常用功能</div>
<div class="result-item" onclick="selectResult(this)">
<div class="result-icon page">🏠</div>
<div class="result-content">
<div class="result-title">首页</div>
<div class="result-subtitle">主页 · 每日推荐</div>
</div>
<span class="result-badge page">页面</span>
</div>
<div class="result-item" onclick="selectResult(this)">
<div class="result-icon feature">📅</div>
<div class="result-content">
<div class="result-title">每日签到</div>
<div class="result-subtitle">功能 · 获取积分奖励</div>
</div>
<span class="result-badge feature">功能</span>
</div>
<div class="result-item" onclick="selectResult(this)">
<div class="result-icon tool">⏱️</div>
<div class="result-content">
<div class="result-title">番茄钟</div>
<div class="result-subtitle">工具 · 专注计时</div>
</div>
<span class="result-badge tool">工具</span>
</div>
<div class="result-item" onclick="selectResult(this)">
<div class="result-icon setting">🎨</div>
<div class="result-content">
<div class="result-title">主题定制</div>
<div class="result-subtitle">设置 · 个性化外观</div>
</div>
<span class="result-badge setting">设置</span>
</div>
</div>
<div class="shortcut-hint">
<span><span class="kbd"></span><span class="kbd"></span> 导航</span>
<span><span class="kbd"></span> 打开</span>
<span><span class="kbd">esc</span> 关闭</span>
</div>
</div>
</div>
</div>
</div>
<!-- 状态3: 搜索浮层 - 搜索结果 -->
<div class="phone-wrapper">
<div class="phone-label">搜索浮层 — 搜索结果</div>
<div class="phone" id="phone-results">
<div class="profile-page" style="filter:blur(2px);">
<div class="profile-header">
<div class="profile-header-icon">👤</div>
<h1>我的</h1>
</div>
</div>
<div class="search-overlay active">
<div class="search-container">
<div class="search-bar">
<span class="search-icon">🔍</span>
<input class="search-input" type="text" value="主" oninput="handleSearch(this, 'results')" id="input-results">
<div class="search-clear visible" onclick="clearSearch('results')"></div>
</div>
<div class="search-results" id="results-results">
<div class="result-category">页面</div>
<div class="result-item selected">
<div class="result-icon page">🏠</div>
<div class="result-content">
<div class="result-title"><mark></mark></div>
<div class="result-subtitle">主导航 · 每日推荐内容</div>
</div>
<span class="result-badge page">页面</span>
</div>
<div class="result-category">功能</div>
<div class="result-item">
<div class="result-icon feature">🔑</div>
<div class="result-content">
<div class="result-title"><mark></mark>题定制</div>
<div class="result-subtitle">个性化 · 颜色/字体/样式</div>
</div>
<span class="result-badge feature">功能</span>
</div>
<div class="result-item">
<div class="result-icon feature">📊</div>
<div class="result-content">
<div class="result-title">数据<mark></mark></div>
<div class="result-subtitle">统计 · 来源数据分析</div>
</div>
<span class="result-badge feature">功能</span>
</div>
<div class="result-category">设置</div>
<div class="result-item">
<div class="result-icon setting">🎨</div>
<div class="result-content">
<div class="result-title"><mark></mark>题设置</div>
<div class="result-subtitle">外观 · 深色/浅色/跟随系统</div>
</div>
<span class="result-badge setting">设置</span>
</div>
<div class="result-category">内容</div>
<div class="result-item">
<div class="result-icon content">📝</div>
<div class="result-content">
<div class="result-title"><mark></mark>页编辑器</div>
<div class="result-subtitle">编辑器 · Markdown写作</div>
</div>
<span class="result-badge content">内容</span>
</div>
</div>
<div class="shortcut-hint">
<span><span class="kbd"></span><span class="kbd"></span> 导航</span>
<span><span class="kbd"></span> 打开</span>
<span><span class="kbd">esc</span> 关闭</span>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- 方案对比 -->
<div class="comparison">
<h3>搜索结果分类说明</h3>
<table class="comparison-table">
<thead>
<tr>
<th>分类</th>
<th>颜色</th>
<th>包含内容</th>
<th>示例</th>
</tr>
</thead>
<tbody>
<tr>
<td><span class="result-badge page">页面</span></td>
<td>蓝色</td>
<td>主导航页面、Tab页面</td>
<td>首页、发现、我的、编辑器</td>
</tr>
<tr>
<td><span class="result-badge feature">功能</span></td>
<td>绿色</td>
<td>功能模块页面</td>
<td>签到、成就、运势、天气、番茄钟</td>
</tr>
<tr>
<td><span class="result-badge tool">工具</span></td>
<td>橙色</td>
<td>工具类页面</td>
<td>汉字、成语、翻译、汇率、OCR</td>
</tr>
<tr>
<td><span class="result-badge setting">设置</span></td>
<td>灰色</td>
<td>设置相关页面</td>
<td>主题、语言、通用、账号、隐私</td>
</tr>
<tr>
<td><span class="result-badge content">内容</span></td>
<td>紫色</td>
<td>内容浏览页面</td>
<td>收藏、历史、笔记、诗词、文章</td>
</tr>
</tbody>
</table>
<h3>交互设计</h3>
<table class="comparison-table">
<thead>
<tr>
<th>交互</th>
<th>触发方式</th>
<th>效果</th>
</tr>
</thead>
<tbody>
<tr>
<td>打开搜索</td>
<td>点击🔍图标 / 下拉手势 / Cmd+K</td>
<td>弹出毛玻璃搜索浮层</td>
</tr>
<tr>
<td>关闭搜索</td>
<td>点击遮罩 / ESC键 / 点击清除</td>
<td>搜索浮层消失,恢复原页面</td>
</tr>
<tr>
<td>实时搜索</td>
<td>输入文字</td>
<td>按分类展示匹配结果,高亮关键词</td>
</tr>
<tr>
<td>选择结果</td>
<td>点击 / 回车</td>
<td>跳转到对应页面</td>
</tr>
<tr>
<td>键盘导航</td>
<td>↑↓ 箭头键</td>
<td>在结果列表中移动选中项</td>
</tr>
<tr>
<td>拼音匹配</td>
<td>输入拼音首字母</td>
<td>匹配中文页面名(如"qt"→"天气"</td>
</tr>
</tbody>
</table>
</div>
<script>
// 搜索数据
const searchData = [
{ name: '首页', category: '页面', type: 'page', icon: '🏠', desc: '主导航 · 每日推荐内容', pinyin: 'shouye', route: '/home' },
{ name: '发现', category: '页面', type: 'page', icon: '🔭', desc: '探索 · 精选内容', pinyin: 'faxian', route: '/discover' },
{ name: '我的', category: '页面', type: 'page', icon: '👤', desc: '个人中心 · 设置', pinyin: 'wode', route: '/profile' },
{ name: '编辑器', category: '页面', type: 'page', icon: '✏️', desc: 'Markdown · 写作', pinyin: 'bianjiqi', route: '/editor' },
{ name: '搜索', category: '页面', type: 'page', icon: '🔍', desc: '全局搜索 · 内容检索', pinyin: 'sousuo', route: '/search' },
{ name: '每日签到', category: '功能', type: 'feature', icon: '📅', desc: '签到 · 获取积分奖励', pinyin: 'meiriqiandao', route: '/signin' },
{ name: '成就中心', category: '功能', type: 'feature', icon: '🏆', desc: '成就 · 勋章收集', pinyin: 'chengjiuzhongxin', route: '/achievement' },
{ name: '每日运势', category: '功能', type: 'feature', icon: '✨', desc: '运势 · 每日一卦', pinyin: 'meiriyunshi', route: '/fortune' },
{ name: '天气', category: '功能', type: 'feature', icon: '🌤️', desc: '天气 · 实时气象', pinyin: 'tianqi', route: '/weather' },
{ name: '番茄钟', category: '功能', type: 'feature', icon: '⏱️', desc: '专注 · 计时器', pinyin: 'fanqiezhong', route: '/pomodoro' },
{ name: '倒计时', category: '功能', type: 'feature', icon: '⏳', desc: '倒计时 · 纪念日', pinyin: 'daojishi', route: '/countdown' },
{ name: '节气', category: '功能', type: 'feature', icon: '🌿', desc: '二十四节气 · 农历', pinyin: 'jieqi', route: '/solar-term' },
{ name: '健康', category: '功能', type: 'feature', icon: '💊', desc: '健康 · 用药提醒', pinyin: 'jiankang', route: '/health' },
{ name: '游戏', category: '功能', type: 'feature', icon: '🎮', desc: '小游戏 · 休闲', pinyin: 'youxi', route: '/game' },
{ name: '汉字', category: '工具', type: 'tool', icon: '字', desc: '汉字查询 · 笔画', pinyin: 'hanzi', route: '/hanzi' },
{ name: '成语', category: '工具', type: 'tool', icon: '典', desc: '成语词典 · 典故', pinyin: 'chengyu', route: '/cy' },
{ name: '翻译', category: '工具', type: 'tool', icon: '🌐', desc: '多语言翻译', pinyin: 'fanyi', route: '/translate' },
{ name: '汇率', category: '工具', type: 'tool', icon: '💱', desc: '汇率换算', pinyin: 'huilv', route: '/exchange-rate' },
{ name: 'OCR', category: '工具', type: 'tool', icon: '📷', desc: '文字识别', pinyin: 'ocr', route: '/ocr' },
{ name: 'RSS', category: '工具', type: 'tool', icon: '📡', desc: 'RSS阅读器', pinyin: 'rss', route: '/rss-reader' },
{ name: '主题定制', category: '设置', type: 'setting', icon: '🎨', desc: '个性化 · 颜色/字体', pinyin: 'zhutidingzhi', route: '/settings/theme' },
{ name: '主题设置', category: '设置', type: 'setting', icon: '🌓', desc: '外观 · 深色/浅色', pinyin: 'zhutishezhi', route: '/settings/theme' },
{ name: '语言', category: '设置', type: 'setting', icon: '🌐', desc: '多语言切换', pinyin: 'yuyan', route: '/settings/language' },
{ name: '通用设置', category: '设置', type: 'setting', icon: '⚙️', desc: '通用 · 偏好设置', pinyin: 'tongyongshezhi', route: '/settings/general' },
{ name: '账号设置', category: '设置', type: 'setting', icon: '🔐', desc: '账号 · 安全', pinyin: 'zhanghaoshezhi', route: '/settings/account' },
{ name: '隐私', category: '设置', type: 'setting', icon: '🛡️', desc: '隐私 · 数据保护', pinyin: 'yinsi', route: '/settings/privacy' },
{ name: '数据管理', category: '设置', type: 'setting', icon: '💾', desc: '数据 · 导入导出', pinyin: 'shujuguanli', route: '/data-management' },
{ name: '收藏', category: '内容', type: 'content', icon: '❤️', desc: '我的收藏', pinyin: 'shoucang', route: '/favorites' },
{ name: '阅读历史', category: '内容', type: 'content', icon: '📖', desc: '浏览记录', pinyin: 'yuedulishi', route: '/history' },
{ name: '笔记', category: '内容', type: 'content', icon: '📝', desc: '我的笔记', pinyin: 'biji', route: '/notes' },
{ name: '诗词', category: '内容', type: 'content', icon: '📜', desc: '古诗词鉴赏', pinyin: 'shici', route: '/poetry' },
{ name: '文章', category: '内容', type: 'content', icon: '📄', desc: '文章阅读', pinyin: 'wenzhang', route: '/articles' },
{ name: '数据总揽', category: '功能', type: 'feature', icon: '📊', desc: '统计 · 来源分析', pinyin: 'shujuzonglan', route: '/statistics' },
{ name: '每日任务', category: '功能', type: 'feature', icon: '✅', desc: '任务 · 积分奖励', pinyin: 'meirirenwu', route: '/daily-task' },
{ name: '用户中心', category: '页面', type: 'page', icon: '👤', desc: '个人信息 · 编辑', pinyin: 'yonghuzhongxin', route: '/user-center' },
{ name: '关于', category: '设置', type: 'setting', icon: '', desc: '版本 · 许可证', pinyin: 'guanyu', route: '/about' },
];
function toggleTheme() {
const body = document.body;
const current = body.getAttribute('data-theme');
body.setAttribute('data-theme', current === 'dark' ? 'light' : 'dark');
}
function showSearch(phoneId) {
const phone = document.getElementById('phone-' + phoneId);
const overlay = phone.querySelector('.search-overlay');
if (overlay) {
overlay.classList.add('active');
const input = overlay.querySelector('.search-input');
if (input) setTimeout(() => input.focus(), 100);
}
}
function hideSearch(event, phoneId) {
if (event.target.classList.contains('search-overlay')) {
event.target.classList.remove('active');
}
}
function clearSearch(phoneId) {
const input = document.getElementById('input-' + phoneId);
if (input) {
input.value = '';
handleSearch(input, phoneId);
}
}
function fillSearch(phoneId, text) {
const input = document.getElementById('input-' + phoneId);
if (input) {
input.value = text;
handleSearch(input, phoneId);
input.focus();
}
}
function handleSearch(input, phoneId) {
const query = input.value.trim().toLowerCase();
const clearBtn = document.getElementById('clear-' + phoneId);
const resultsContainer = document.getElementById('results-' + phoneId);
if (clearBtn) {
clearBtn.classList.toggle('visible', query.length > 0);
}
if (!query) {
// 恢复默认状态
resultsContainer.innerHTML = `
<div class="result-category">最近搜索</div>
<div class="recent-tags">
<span class="recent-tag" onclick="fillSearch('${phoneId}', '天气')">天气</span>
<span class="recent-tag" onclick="fillSearch('${phoneId}', '笔记')">笔记</span>
<span class="recent-tag" onclick="fillSearch('${phoneId}', '主题')">主题</span>
<span class="recent-tag" onclick="fillSearch('${phoneId}', '番茄钟')">番茄钟</span>
<span class="recent-tag" onclick="fillSearch('${phoneId}', '签到')">签到</span>
</div>
<div class="result-category">常用功能</div>
<div class="result-item">
<div class="result-icon page">🏠</div>
<div class="result-content">
<div class="result-title">首页</div>
<div class="result-subtitle">主页 · 每日推荐</div>
</div>
<span class="result-badge page">页面</span>
</div>
<div class="result-item">
<div class="result-icon feature">📅</div>
<div class="result-content">
<div class="result-title">每日签到</div>
<div class="result-subtitle">功能 · 获取积分奖励</div>
</div>
<span class="result-badge feature">功能</span>
</div>
<div class="result-item">
<div class="result-icon tool">⏱️</div>
<div class="result-content">
<div class="result-title">番茄钟</div>
<div class="result-subtitle">工具 · 专注计时</div>
</div>
<span class="result-badge tool">工具</span>
</div>
<div class="result-item">
<div class="result-icon setting">🎨</div>
<div class="result-content">
<div class="result-title">主题定制</div>
<div class="result-subtitle">设置 · 个性化外观</div>
</div>
<span class="result-badge setting">设置</span>
</div>
`;
return;
}
// 搜索匹配
const results = searchData.filter(item => {
return item.name.toLowerCase().includes(query) ||
item.pinyin.includes(query) ||
item.desc.toLowerCase().includes(query) ||
item.pinyin.split('').filter((c, i) => i === 0 || item.pinyin[i-1] === ' ').join('').includes(query);
});
if (results.length === 0) {
resultsContainer.innerHTML = `
<div class="empty-state">
<div class="empty-icon">🔍</div>
<div class="empty-text">未找到"${query}"相关结果</div>
<div class="empty-hint">试试其他关键词或拼音首字母</div>
</div>
`;
return;
}
// 按分类分组
const grouped = {};
const categoryOrder = ['页面', '功能', '工具', '设置', '内容'];
results.forEach(item => {
if (!grouped[item.category]) grouped[item.category] = [];
grouped[item.category].push(item);
});
let html = '';
categoryOrder.forEach(cat => {
if (!grouped[cat]) return;
html += `<div class="result-category">${cat}</div>`;
grouped[cat].forEach(item => {
const highlighted = highlightText(item.name, query);
html += `
<div class="result-item" onclick="selectResult(this)">
<div class="result-icon ${item.type}">${item.icon}</div>
<div class="result-content">
<div class="result-title">${highlighted}</div>
<div class="result-subtitle">${item.desc}</div>
</div>
<span class="result-badge ${item.type}">${cat}</span>
</div>
`;
});
});
resultsContainer.innerHTML = html;
}
function highlightText(text, query) {
if (!query) return text;
const regex = new RegExp(`(${query.replace(/[.*+?^${}()|[\]\\]/g, '\\$&')})`, 'gi');
return text.replace(regex, '<mark>$1</mark>');
}
function selectResult(el) {
el.style.background = 'var(--primary)';
el.style.color = 'white';
el.style.borderRadius = '8px';
el.style.margin = '0 4px';
el.style.transition = 'all 0.15s';
setTimeout(() => {
el.style.background = '';
el.style.color = '';
el.style.borderRadius = '';
el.style.margin = '';
}, 300);
}
</script>
</body>
</html>