feat(public): 主题切换改为下拉菜单 + 新增4个主题 + 优化搜索与抽屉交互
- 主题切换由循环切换改为弹出下拉菜单,显示全部可用主题 - 新增紫韵/深海/青空/玫红 4 个主题,共 8 个主题 + 跟随系统 - 清理顶部 .actions 菜单栏与旧主题下拉的残余死 CSS/JS - 搜索无结果时显示空态提示 - 移动端抽屉打开时锁定背景滚动 - 搜索输入防抖 120ms - 超宽屏下卡片描述放宽到 2 行,搜索框同步放大 - 修复抽屉主题按钮缺少 JS 绑定的 bug - .card .url 对比度由 --text-soft 改为 --text-muted
This commit is contained in:
+210
-138
@@ -91,6 +91,62 @@
|
|||||||
--shadow: 0 2px 12px rgba(0,0,0,0.4);
|
--shadow: 0 2px 12px rgba(0,0,0,0.4);
|
||||||
--shadow-hover: 0 8px 24px rgba(22, 186, 170, 0.25);
|
--shadow-hover: 0 8px 24px rgba(22, 186, 170, 0.25);
|
||||||
}
|
}
|
||||||
|
/* 紫韵(优雅紫色) */
|
||||||
|
[data-theme="lavender"] {
|
||||||
|
--brand: #8b5cf6;
|
||||||
|
--brand-2: #ec4899;
|
||||||
|
--bg: #faf5ff;
|
||||||
|
--card-bg: #ffffff;
|
||||||
|
--text: #2e1065;
|
||||||
|
--text-muted: #6d28d9;
|
||||||
|
--text-soft: #a78bfa;
|
||||||
|
--border: #e9d5ff;
|
||||||
|
--topbar-text: #ffffff;
|
||||||
|
--shadow: 0 2px 12px rgba(139,92,246,0.10);
|
||||||
|
--shadow-hover: 0 8px 24px rgba(139,92,246,0.25);
|
||||||
|
}
|
||||||
|
/* 深海(深蓝 navy) */
|
||||||
|
[data-theme="ocean"] {
|
||||||
|
--brand: #0ea5e9;
|
||||||
|
--brand-2: #06b6d4;
|
||||||
|
--bg: #f0f9ff;
|
||||||
|
--card-bg: #ffffff;
|
||||||
|
--text: #0c4a6e;
|
||||||
|
--text-muted: #0369a1;
|
||||||
|
--text-soft: #7dd3fc;
|
||||||
|
--border: #bae6fd;
|
||||||
|
--topbar-text: #ffffff;
|
||||||
|
--shadow: 0 2px 12px rgba(14,165,233,0.10);
|
||||||
|
--shadow-hover: 0 8px 24px rgba(14,165,233,0.28);
|
||||||
|
}
|
||||||
|
/* 青空(明亮天蓝) */
|
||||||
|
[data-theme="sky"] {
|
||||||
|
--brand: #38bdf8;
|
||||||
|
--brand-2: #3b82f6;
|
||||||
|
--bg: #f0f9ff;
|
||||||
|
--card-bg: #ffffff;
|
||||||
|
--text: #0c4a6e;
|
||||||
|
--text-muted: #0284c7;
|
||||||
|
--text-soft: #7dd3fc;
|
||||||
|
--border: #e0f2fe;
|
||||||
|
--topbar-text: #ffffff;
|
||||||
|
--shadow: 0 2px 12px rgba(59,130,246,0.10);
|
||||||
|
--shadow-hover: 0 8px 24px rgba(59,130,246,0.28);
|
||||||
|
}
|
||||||
|
/* 玫红(热情玫红) */
|
||||||
|
[data-theme="rose"] {
|
||||||
|
--brand: #f43f5e;
|
||||||
|
--brand-2: #ec4899;
|
||||||
|
--bg: #fff1f2;
|
||||||
|
--card-bg: #ffffff;
|
||||||
|
--text: #4a040c;
|
||||||
|
--text-muted: #be123c;
|
||||||
|
--text-soft: #fda4af;
|
||||||
|
--border: #fecdd3;
|
||||||
|
--topbar-text: #ffffff;
|
||||||
|
--shadow: 0 2px 12px rgba(244,63,94,0.10);
|
||||||
|
--shadow-hover: 0 8px 24px rgba(244,63,94,0.28);
|
||||||
|
}
|
||||||
/* 系统暗色兜底:未设置 data-theme 时跟随系统 */
|
/* 系统暗色兜底:未设置 data-theme 时跟随系统 */
|
||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
:root:not([data-theme]) {
|
:root:not([data-theme]) {
|
||||||
@@ -157,85 +213,15 @@
|
|||||||
.topbar { padding: 68px 0 52px; }
|
.topbar { padding: 68px 0 52px; }
|
||||||
.topbar h1 { font-size: 44px; }
|
.topbar h1 { font-size: 44px; }
|
||||||
.topbar .sub { font-size: 17px; }
|
.topbar .sub { font-size: 17px; }
|
||||||
.site-search { max-width: 680px; }
|
.site-search { max-width: 760px; }
|
||||||
|
/* 卡片描述放宽到 2 行,提升信息密度 */
|
||||||
|
.card .desc { -webkit-line-clamp: 2; min-height: 40px; }
|
||||||
}
|
}
|
||||||
@media (min-width: 2560px) {
|
@media (min-width: 2560px) {
|
||||||
.topbar { padding: 84px 0 64px; }
|
.topbar { padding: 84px 0 64px; }
|
||||||
.topbar h1 { font-size: 52px; }
|
.topbar h1 { font-size: 52px; }
|
||||||
|
.site-search { max-width: 880px; }
|
||||||
}
|
}
|
||||||
.topbar .actions { margin-top: 18px; display: flex; flex-wrap: wrap; gap: 8px; }
|
|
||||||
.topbar .actions a, .topbar .actions button {
|
|
||||||
display: inline-flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 4px;
|
|
||||||
padding: 6px 14px;
|
|
||||||
background: rgba(255,255,255,0.18);
|
|
||||||
border: 1px solid rgba(255,255,255,0.35);
|
|
||||||
color: var(--topbar-text);
|
|
||||||
border-radius: 999px;
|
|
||||||
font-size: 13px;
|
|
||||||
text-decoration: none;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background 0.2s;
|
|
||||||
font-family: inherit;
|
|
||||||
}
|
|
||||||
.topbar .actions a:hover, .topbar .actions button:hover { background: rgba(255,255,255,0.32); }
|
|
||||||
|
|
||||||
/* ===== 主题切换下拉 ===== */
|
|
||||||
.theme-picker { position: relative; display: inline-block; }
|
|
||||||
.theme-picker > button {
|
|
||||||
display: inline-flex; align-items: center; gap: 4px;
|
|
||||||
}
|
|
||||||
.theme-menu {
|
|
||||||
position: absolute;
|
|
||||||
top: calc(100% + 6px);
|
|
||||||
right: 0;
|
|
||||||
min-width: 180px;
|
|
||||||
margin: 0; padding: 4px;
|
|
||||||
list-style: none;
|
|
||||||
background: var(--card-bg);
|
|
||||||
color: var(--text);
|
|
||||||
border: 1px solid var(--border);
|
|
||||||
border-radius: 10px;
|
|
||||||
box-shadow: var(--shadow-hover);
|
|
||||||
z-index: 50;
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateY(-6px);
|
|
||||||
pointer-events: none;
|
|
||||||
transition: opacity 0.15s, transform 0.15s;
|
|
||||||
}
|
|
||||||
.theme-menu.open {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translateY(0);
|
|
||||||
pointer-events: auto;
|
|
||||||
}
|
|
||||||
.theme-menu li {
|
|
||||||
display: flex; align-items: center; gap: 10px;
|
|
||||||
padding: 8px 12px;
|
|
||||||
font-size: 14px;
|
|
||||||
border-radius: 6px;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: background 0.12s;
|
|
||||||
color: var(--text);
|
|
||||||
}
|
|
||||||
.theme-menu li:hover { background: rgba(22,186,170,0.10); }
|
|
||||||
.theme-menu li.active { background: rgba(22,186,170,0.18); font-weight: 600; }
|
|
||||||
.theme-menu li .dot {
|
|
||||||
display: inline-block;
|
|
||||||
width: 18px; height: 18px;
|
|
||||||
border-radius: 50%;
|
|
||||||
border: 2px solid var(--border);
|
|
||||||
flex-shrink: 0;
|
|
||||||
}
|
|
||||||
.dot-default { background: linear-gradient(135deg, #16baaa 0%, #2e8de8 100%); }
|
|
||||||
.dot-sunset { background: linear-gradient(135deg, #ff7043 0%, #e91e63 100%); }
|
|
||||||
.dot-forest { background: linear-gradient(135deg, #2e7d32 0%, #00897b 100%); }
|
|
||||||
.dot-dark { background: linear-gradient(135deg, #0f1419 0%, #16baaa 100%); }
|
|
||||||
.dot-auto {
|
|
||||||
background: linear-gradient(90deg, #f5f7fa 0%, #f5f7fa 50%, #0f1419 50%, #0f1419 100%);
|
|
||||||
border-color: var(--text-muted);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 手机端分类入口按钮:默认桌面隐藏 */
|
/* 手机端分类入口按钮:默认桌面隐藏 */
|
||||||
.cat-trigger-mobile {
|
.cat-trigger-mobile {
|
||||||
display: none;
|
display: none;
|
||||||
@@ -251,6 +237,36 @@
|
|||||||
}
|
}
|
||||||
.cat-trigger-mobile:active { background: rgba(255,255,255,0.32); }
|
.cat-trigger-mobile:active { background: rgba(255,255,255,0.32); }
|
||||||
|
|
||||||
|
/* ===== 主题下拉菜单 ===== */
|
||||||
|
.theme-picker-trigger { position: relative; }
|
||||||
|
.theme-menu {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
top: calc(100% + 6px);
|
||||||
|
left: 0;
|
||||||
|
min-width: 150px;
|
||||||
|
margin: 0; padding: 4px;
|
||||||
|
list-style: none;
|
||||||
|
background: var(--card-bg);
|
||||||
|
color: var(--text);
|
||||||
|
border: 1px solid var(--border);
|
||||||
|
border-radius: 10px;
|
||||||
|
box-shadow: var(--shadow-hover);
|
||||||
|
z-index: 50;
|
||||||
|
}
|
||||||
|
.theme-menu.open { display: block; }
|
||||||
|
.theme-menu li {
|
||||||
|
display: block;
|
||||||
|
padding: 8px 12px;
|
||||||
|
font-size: 14px;
|
||||||
|
border-radius: 6px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background 0.12s;
|
||||||
|
color: var(--text);
|
||||||
|
}
|
||||||
|
.theme-menu li:hover { background: rgba(22,186,170,0.10); }
|
||||||
|
.theme-menu li.active { background: rgba(22,186,170,0.18); font-weight: 600; }
|
||||||
|
|
||||||
/* ===== 顶部全局搜索 ===== */
|
/* ===== 顶部全局搜索 ===== */
|
||||||
.site-search {
|
.site-search {
|
||||||
position: relative;
|
position: relative;
|
||||||
@@ -307,7 +323,7 @@
|
|||||||
-webkit-backdrop-filter: saturate(180%) blur(8px);
|
-webkit-backdrop-filter: saturate(180%) blur(8px);
|
||||||
}
|
}
|
||||||
.cat-nav-inner {
|
.cat-nav-inner {
|
||||||
max-width: 1200px;
|
max-width: 100%;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 8px 24px;
|
padding: 8px 24px;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -358,6 +374,17 @@
|
|||||||
background: rgba(0,0,0,0.5);
|
background: rgba(0,0,0,0.5);
|
||||||
}
|
}
|
||||||
.cat-drawer.open { display: block; }
|
.cat-drawer.open { display: block; }
|
||||||
|
/* 抽屉打开时锁定背景滚动 */
|
||||||
|
body.drawer-open { overflow: hidden; }
|
||||||
|
|
||||||
|
/* 搜索无结果空态 */
|
||||||
|
.search-empty {
|
||||||
|
text-align: center;
|
||||||
|
color: var(--text-muted);
|
||||||
|
padding: 64px 16px;
|
||||||
|
font-size: 15px;
|
||||||
|
}
|
||||||
|
.search-empty .ico { font-size: 40px; display: block; margin-bottom: 12px; opacity: 0.6; }
|
||||||
.cat-drawer-panel {
|
.cat-drawer-panel {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0; right: 0; bottom: 0;
|
left: 0; right: 0; bottom: 0;
|
||||||
@@ -606,7 +633,7 @@
|
|||||||
min-height: 20px;
|
min-height: 20px;
|
||||||
}
|
}
|
||||||
.card .url {
|
.card .url {
|
||||||
font-size: 12px; color: var(--text-soft);
|
font-size: 12px; color: var(--text-muted);
|
||||||
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
||||||
direction: rtl;
|
direction: rtl;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
@@ -785,7 +812,6 @@
|
|||||||
gap: 10px;
|
gap: 10px;
|
||||||
}
|
}
|
||||||
.topbar-brand { display: none; } /* 手机顶部只保留分类按钮+搜索 */
|
.topbar-brand { display: none; } /* 手机顶部只保留分类按钮+搜索 */
|
||||||
.topbar .actions { display: none; }
|
|
||||||
.cat-trigger-mobile { display: inline-flex; }
|
.cat-trigger-mobile { display: inline-flex; }
|
||||||
|
|
||||||
/* 顶部搜索框更紧凑,占满剩余空间 */
|
/* 顶部搜索框更紧凑,占满剩余空间 */
|
||||||
@@ -966,14 +992,28 @@
|
|||||||
<li><a href="/system/passport/login">
|
<li><a href="/system/passport/login">
|
||||||
<i class="layui-icon side-ico layui-icon-password"></i>
|
<i class="layui-icon side-ico layui-icon-password"></i>
|
||||||
<span class="side-txt">登录后台</span></a></li>
|
<span class="side-txt">登录后台</span></a></li>
|
||||||
<li><a href="javascript:void(0)" id="side-theme-toggle">
|
<li class="theme-picker-trigger">
|
||||||
<i class="layui-icon side-ico layui-icon-light"></i>
|
<a href="javascript:void(0)" id="side-theme-toggle">
|
||||||
<span class="side-txt">切换主题</span></a></li>
|
<i class="layui-icon side-ico layui-icon-light"></i>
|
||||||
|
<span class="side-txt">切换主题</span></a>
|
||||||
|
<ul class="theme-menu" id="side-theme-menu">
|
||||||
|
<li data-theme="default">蓝绿</li>
|
||||||
|
<li data-theme="sunset">暮色</li>
|
||||||
|
<li data-theme="forest">森林</li>
|
||||||
|
<li data-theme="dark">暗色</li>
|
||||||
|
<li data-theme="lavender">紫韵</li>
|
||||||
|
<li data-theme="ocean">深海</li>
|
||||||
|
<li data-theme="sky">青空</li>
|
||||||
|
<li data-theme="rose">玫红</li>
|
||||||
|
<li data-theme="auto">跟随系统</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</aside>
|
</aside>
|
||||||
|
|
||||||
<main class="content">
|
<main class="content">
|
||||||
|
<div id="search-empty" class="search-empty" hidden></div>
|
||||||
{% block content %}{% endblock %}
|
{% block content %}{% endblock %}
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
@@ -1064,10 +1104,23 @@
|
|||||||
<i class="layui-icon cat-icon layui-icon-password"></i>
|
<i class="layui-icon cat-icon layui-icon-password"></i>
|
||||||
<span>登录后台</span>
|
<span>登录后台</span>
|
||||||
<span class="arrow">→</span></a></li>
|
<span class="arrow">→</span></a></li>
|
||||||
<li><a href="javascript:void(0)" id="drawer-theme-toggle">
|
<li class="theme-picker-trigger">
|
||||||
<i class="layui-icon cat-icon layui-icon-light"></i>
|
<a href="javascript:void(0)" id="drawer-theme-toggle">
|
||||||
<span>切换主题</span>
|
<i class="layui-icon cat-icon layui-icon-light"></i>
|
||||||
<span class="arrow">→</span></a></li>
|
<span>切换主题</span>
|
||||||
|
<span class="arrow">→</span></a>
|
||||||
|
<ul class="theme-menu" id="drawer-theme-menu">
|
||||||
|
<li data-theme="default">蓝绿</li>
|
||||||
|
<li data-theme="sunset">暮色</li>
|
||||||
|
<li data-theme="forest">森林</li>
|
||||||
|
<li data-theme="dark">暗色</li>
|
||||||
|
<li data-theme="lavender">紫韵</li>
|
||||||
|
<li data-theme="ocean">深海</li>
|
||||||
|
<li data-theme="sky">青空</li>
|
||||||
|
<li data-theme="rose">玫红</li>
|
||||||
|
<li data-theme="auto">跟随系统</li>
|
||||||
|
</ul>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -1080,13 +1133,6 @@
|
|||||||
var THEME_KEY = 'bw-theme';
|
var THEME_KEY = 'bw-theme';
|
||||||
var FIXED_THEMES = ['default', 'sunset', 'forest', 'dark'];
|
var FIXED_THEMES = ['default', 'sunset', 'forest', 'dark'];
|
||||||
var ALL = FIXED_THEMES.concat(['auto']);
|
var ALL = FIXED_THEMES.concat(['auto']);
|
||||||
var LABEL_MAP = {
|
|
||||||
'default': '🎨 蓝绿',
|
|
||||||
'sunset': '🎨 暮色',
|
|
||||||
'forest': '🎨 森林',
|
|
||||||
'dark': '🎨 暗色',
|
|
||||||
'auto': '🎨 跟随系统'
|
|
||||||
};
|
|
||||||
|
|
||||||
function isSystemDark(){
|
function isSystemDark(){
|
||||||
return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||||
@@ -1103,8 +1149,12 @@
|
|||||||
if (ALL.indexOf(name) === -1) name = 'default';
|
if (ALL.indexOf(name) === -1) name = 'default';
|
||||||
var resolved = resolveTheme(name);
|
var resolved = resolveTheme(name);
|
||||||
document.documentElement.setAttribute('data-theme', resolved);
|
document.documentElement.setAttribute('data-theme', resolved);
|
||||||
// 顶部 meta 颜色随主题变化
|
// 顶部 meta 颜色随主题变化(暗色用深色,其他用对应品牌色)
|
||||||
var themeColor = (resolved === 'dark') ? '#0f1419' : '#16baaa';
|
var themeColor = (resolved === 'dark') ? '#0f1419' :
|
||||||
|
(resolved === 'lavender') ? '#8b5cf6' :
|
||||||
|
(resolved === 'ocean') ? '#0ea5e9' :
|
||||||
|
(resolved === 'sky') ? '#38bdf8' :
|
||||||
|
(resolved === 'rose') ? '#f43f5e' : '#16baaa';
|
||||||
var meta = document.querySelector('meta[name="theme-color"]');
|
var meta = document.querySelector('meta[name="theme-color"]');
|
||||||
if (meta) meta.setAttribute('content', themeColor);
|
if (meta) meta.setAttribute('content', themeColor);
|
||||||
// 高亮菜单项
|
// 高亮菜单项
|
||||||
@@ -1112,9 +1162,6 @@
|
|||||||
if (li.getAttribute('data-theme') === name) li.classList.add('active');
|
if (li.getAttribute('data-theme') === name) li.classList.add('active');
|
||||||
else li.classList.remove('active');
|
else li.classList.remove('active');
|
||||||
});
|
});
|
||||||
// 更新顶部按钮文字
|
|
||||||
var label = document.getElementById('theme-toggle-label');
|
|
||||||
if (label) label.textContent = LABEL_MAP[name] || '🎨 主题';
|
|
||||||
if (persist) localStorage.setItem(THEME_KEY, name);
|
if (persist) localStorage.setItem(THEME_KEY, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1227,9 +1274,11 @@
|
|||||||
|
|
||||||
function openDrawer(){
|
function openDrawer(){
|
||||||
drawer.classList.add('open');
|
drawer.classList.add('open');
|
||||||
|
document.body.classList.add('drawer-open'); // 锁背景滚动
|
||||||
}
|
}
|
||||||
function closeDrawer(){
|
function closeDrawer(){
|
||||||
drawer.classList.remove('open');
|
drawer.classList.remove('open');
|
||||||
|
document.body.classList.remove('drawer-open');
|
||||||
}
|
}
|
||||||
if (triggerMobile) triggerMobile.addEventListener('click', openDrawer);
|
if (triggerMobile) triggerMobile.addEventListener('click', openDrawer);
|
||||||
if (fab) fab.addEventListener('click', openDrawer);
|
if (fab) fab.addEventListener('click', openDrawer);
|
||||||
@@ -1263,32 +1312,6 @@
|
|||||||
link.addEventListener('click', closeDrawer);
|
link.addEventListener('click', closeDrawer);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// 抽屉内"切换主题"按钮:循环到下一个主题(含 auto)
|
|
||||||
var drawerThemeBtn = document.getElementById('drawer-theme-toggle');
|
|
||||||
if (drawerThemeBtn) {
|
|
||||||
drawerThemeBtn.addEventListener('click', function(e){
|
|
||||||
e.preventDefault();
|
|
||||||
var VALID = ['default', 'sunset', 'forest', 'dark', 'auto'];
|
|
||||||
var LABEL_MAP = {default:'🎨 蓝绿', sunset:'🎨 暮色', forest:'🎨 森林', dark:'🎨 暗色', auto:'🎨 跟随系统'};
|
|
||||||
var cur = localStorage.getItem('bw-theme') || 'default';
|
|
||||||
var idx = VALID.indexOf(cur);
|
|
||||||
var next = VALID[(idx + 1) % VALID.length];
|
|
||||||
// 解析 next 为实际生效值
|
|
||||||
var isSystemDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
||||||
var resolved = (next === 'auto') ? (isSystemDark ? 'dark' : 'default') : next;
|
|
||||||
document.documentElement.setAttribute('data-theme', resolved);
|
|
||||||
var labelEl = document.getElementById('theme-toggle-label');
|
|
||||||
if (labelEl) labelEl.textContent = LABEL_MAP[next];
|
|
||||||
localStorage.setItem('bw-theme', next);
|
|
||||||
// 同步菜单高亮
|
|
||||||
document.querySelectorAll('.theme-menu li').forEach(function(li){
|
|
||||||
if (li.getAttribute('data-theme') === next) li.classList.add('active');
|
|
||||||
else li.classList.remove('active');
|
|
||||||
});
|
|
||||||
closeDrawer();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
// ===== 导航卡片点击埋点:sendBeacon,不影响原 href 跳转 =====
|
// ===== 导航卡片点击埋点:sendBeacon,不影响原 href 跳转 =====
|
||||||
@@ -1526,10 +1549,26 @@
|
|||||||
if (cnt) cnt.textContent = n ? String(n) : '';
|
if (cnt) cnt.textContent = n ? String(n) : '';
|
||||||
li.style.display = n ? '' : 'none';
|
li.style.display = n ? '' : 'none';
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 无结果空态
|
||||||
|
var empty = document.getElementById('search-empty');
|
||||||
|
if (empty) {
|
||||||
|
var totalVisible = document.querySelectorAll('.grid .card:not([style*="display: none"])').length;
|
||||||
|
if (keyword && totalVisible === 0) {
|
||||||
|
empty.innerHTML = '<span class="ico">🔍</span>未找到与「' + keyword + '」匹配的网址';
|
||||||
|
empty.hidden = false;
|
||||||
|
} else {
|
||||||
|
empty.hidden = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 输入防抖,避免每次按键都遍历全部卡片
|
||||||
|
var t;
|
||||||
input.addEventListener('input', function(){
|
input.addEventListener('input', function(){
|
||||||
filter(input.value);
|
clearTimeout(t);
|
||||||
|
var v = input.value;
|
||||||
|
t = setTimeout(function(){ filter(v); }, 120);
|
||||||
});
|
});
|
||||||
|
|
||||||
form.addEventListener('submit', function(e){
|
form.addEventListener('submit', function(e){
|
||||||
@@ -1557,26 +1596,59 @@
|
|||||||
filter(q || '');
|
filter(q || '');
|
||||||
})();
|
})();
|
||||||
|
|
||||||
// ===== 侧栏「切换主题」:循环切换到下一个主题 =====
|
// ===== 侧栏「切换主题」:弹出下拉菜单 =====
|
||||||
(function(){
|
(function(){
|
||||||
var btn = document.getElementById('side-theme-toggle');
|
var btn = document.getElementById('side-theme-toggle');
|
||||||
if (!btn) return;
|
var menu = document.getElementById('side-theme-menu');
|
||||||
|
if (!btn || !menu) return;
|
||||||
|
function closeAll(){
|
||||||
|
document.querySelectorAll('.theme-menu.open').forEach(function(m){ m.classList.remove('open'); });
|
||||||
|
}
|
||||||
btn.addEventListener('click', function(e){
|
btn.addEventListener('click', function(e){
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var VALID = ['default', 'sunset', 'forest', 'dark', 'auto'];
|
e.stopPropagation();
|
||||||
var LABEL_MAP = {default:'🎨 蓝绿', sunset:'🎨 暮色', forest:'🎨 森林', dark:'🎨 暗色', auto:'🎨 跟随系统'};
|
var wasOpen = menu.classList.contains('open');
|
||||||
var cur = localStorage.getItem('bw-theme') || 'default';
|
closeAll();
|
||||||
var next = VALID[(VALID.indexOf(cur) + 1) % VALID.length];
|
if (!wasOpen) menu.classList.add('open');
|
||||||
var isDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
|
||||||
var resolved = (next === 'auto') ? (isDark ? 'dark' : 'default') : next;
|
|
||||||
document.documentElement.setAttribute('data-theme', resolved);
|
|
||||||
var label = document.getElementById('theme-toggle-label');
|
|
||||||
if (label) label.textContent = LABEL_MAP[next];
|
|
||||||
localStorage.setItem('bw-theme', next);
|
|
||||||
document.querySelectorAll('.theme-menu li').forEach(function(li){
|
|
||||||
li.classList.toggle('active', li.getAttribute('data-theme') === next);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
menu.addEventListener('click', function(e){
|
||||||
|
var li = e.target.closest('li[data-theme]');
|
||||||
|
if (!li) return;
|
||||||
|
e.stopPropagation();
|
||||||
|
applyTheme(li.getAttribute('data-theme'), true);
|
||||||
|
closeAll();
|
||||||
|
});
|
||||||
|
document.addEventListener('click', closeAll);
|
||||||
|
document.addEventListener('keydown', function(e){ if (e.key === 'Escape') closeAll(); });
|
||||||
|
})();
|
||||||
|
|
||||||
|
// ===== 抽屉内「切换主题」:弹出下拉菜单 =====
|
||||||
|
(function(){
|
||||||
|
var btn = document.getElementById('drawer-theme-toggle');
|
||||||
|
var menu = document.getElementById('drawer-theme-menu');
|
||||||
|
if (!btn || !menu) return;
|
||||||
|
function closeAll(){
|
||||||
|
document.querySelectorAll('.theme-menu.open').forEach(function(m){ m.classList.remove('open'); });
|
||||||
|
}
|
||||||
|
btn.addEventListener('click', function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
var wasOpen = menu.classList.contains('open');
|
||||||
|
closeAll();
|
||||||
|
if (!wasOpen) menu.classList.add('open');
|
||||||
|
});
|
||||||
|
menu.addEventListener('click', function(e){
|
||||||
|
var li = e.target.closest('li[data-theme]');
|
||||||
|
if (!li) return;
|
||||||
|
e.stopPropagation();
|
||||||
|
applyTheme(li.getAttribute('data-theme'), true);
|
||||||
|
closeAll();
|
||||||
|
// 关闭抽屉
|
||||||
|
var drawer = document.getElementById('cat-drawer');
|
||||||
|
if (drawer) drawer.classList.remove('open');
|
||||||
|
});
|
||||||
|
document.addEventListener('click', closeAll);
|
||||||
|
document.addEventListener('keydown', function(e){ if (e.key === 'Escape') closeAll(); });
|
||||||
})();
|
})();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
Reference in New Issue
Block a user