From bd0ace8d9e3f71a3ca2a725634d2ec9a7eaec453 Mon Sep 17 00:00:00 2001 From: Zuoling Rong Date: Sat, 3 May 2025 02:22:04 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96ui=E5=B8=83=E5=B1=80=20and=20?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BE=A7=E8=BE=B9=E6=A0=8F=E6=94=B6=E5=9B=9E?= =?UTF-8?q?=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/style.css | 310 +++++++++++++++++++++++++++++++++++++------ src/script.js | 48 +++++++ templates/index.html | 3 + 3 files changed, 321 insertions(+), 40 deletions(-) diff --git a/assets/style.css b/assets/style.css index 4d875ae..58f629b 100644 --- a/assets/style.css +++ b/assets/style.css @@ -24,6 +24,8 @@ --white-color: #ffffff; --gradient-color: linear-gradient(135deg, #4a9eff 0%, #a855f7 50%, #ff6b6b 100%); --gradient-color-simple: linear-gradient(135deg, #4a9eff 0%, #a855f7 100%); + --sidebar-width: 240px; + --sidebar-collapsed-width: 60px; } /* 浅色主题 */ @@ -221,7 +223,7 @@ body.loaded .layout { /* 侧边栏样式 */ .sidebar { - width: 240px; + width: var(--sidebar-width); background-color: var(--sidebar-bg); position: fixed; top: 0; @@ -244,13 +246,129 @@ body.loaded .layout { scrollbar-width: thin; /* Firefox */ scrollbar-color: var(--scrollbar-color) transparent; /* Firefox */ overflow-y: hidden; /* 防止整个侧边栏滚动 */ - transition: background-color 0.3s ease, transform 0.3s ease; + transition: width 0.3s ease, background-color 0.3s ease, transform 0.3s ease; +} + +/* 侧边栏折叠状态 */ +.sidebar.collapsed { + width: var(--sidebar-collapsed-width); + overflow-x: hidden; +} + +/* 优化侧边栏折叠时的Logo部分 */ +.sidebar.collapsed .logo { + padding: 1.2rem 0.5rem 0.6rem; + justify-content: center; + display: flex; + align-items: center; + height: 60px; /* 确保与展开状态高度一致 */ +} + +/* 折叠状态下的侧边栏内容区域调整 */ +.sidebar.collapsed .sidebar-content { + padding: 0; + scrollbar-width: none; /* 隐藏滚动条 */ +} + +/* 调整折叠侧边栏的部分元素间距 */ +.sidebar.collapsed .nav-section { + gap: 2px; +} + +/* 减小折叠状态下的版权区域高度 */ +.sidebar.collapsed .copyright { + padding: 0.4rem; + height: 0; + min-height: 0; + border-top: none; +} + +.sidebar.collapsed .sidebar-content::-webkit-scrollbar { + display: none; /* 隐藏WebKit浏览器的滚动条 */ } /* 侧边栏头部区域 */ .sidebar .logo { grid-area: header; - padding: 1.5rem 1.2rem 0.8rem; /* 调整上下padding更均衡 */ + padding: 1.2rem 1.2rem 0.6rem; /* 调整上下padding更紧凑 */ + display: flex; + align-items: center; + justify-content: space-between; + overflow: hidden; /* 防止内容溢出 */ + position: relative; /* 添加相对定位,作为按钮的参考 */ + height: 60px; /* 固定高度,确保两种状态下一致 */ +} + +.logo h1 { + font-size: 1.4rem; + color: var(--text-bright); + margin-bottom: 0; + padding-left: 0.5rem; + letter-spacing: 0.5px; + transition: opacity 0.3s ease, transform 0.3s ease, width 0.3s ease; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + flex: 1; +} + +/* 侧边栏折叠按钮 */ +.sidebar-toggle { + background: transparent; + border: none; + color: var(--accent-color); + height: 28px; + width: 28px; + border-radius: 50%; + display: flex; + align-items: center; + justify-content: center; + cursor: pointer; + transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1); + margin-left: 8px; + padding: 0; + flex-shrink: 0; /* 防止按钮被压缩 */ + position: absolute; /* 绝对定位 */ + right: 16px; /* 右侧对齐 */ + top: 50%; /* 垂直居中 */ + transform: translateY(-50%); /* 精确垂直居中 */ +} + +.sidebar-toggle .toggle-icon { + font-size: 0.9rem; + transition: transform 0.3s ease; +} + +.sidebar-toggle:hover { + background: var(--secondary-bg); + transform: translateY(-2px) translateY(-50%); +} + +.sidebar-toggle:active { + transform: translateY(0) translateY(-50%); +} + +.sidebar.collapsed .sidebar-toggle { + position: absolute; /* 保持绝对定位 */ + right: 50%; /* 在折叠状态下水平居中 */ + top: 50%; + transform: translate(50%, -50%); /* 精确居中定位 */ + margin: 0; /* 移除边距 */ + height: 24px; + width: 24px; +} + +.sidebar.collapsed .sidebar-toggle:hover { + transform: translate(50%, -52%); +} + +.sidebar.collapsed .sidebar-toggle:active { + transform: translate(50%, -50%); +} + +/* 侧边栏折叠状态下的按钮图标旋转180度 */ +.sidebar.collapsed .toggle-icon { + transform: rotate(180deg); } /* 侧边栏内容区域 - 可滚动 */ @@ -260,57 +378,42 @@ body.loaded .layout { padding: 0 1.2rem; display: flex; flex-direction: column; - gap: 1rem; /* 从2rem减小到1rem */ + gap: 0.6rem; /* 从1rem减小到0.6rem */ /* 自定义滚动条样式 */ scrollbar-width: thin; /* Firefox */ scrollbar-color: var(--scrollbar-color) transparent; /* Firefox */ } -/* 侧边栏底部区域 - 版权信息 */ -.sidebar .copyright { - grid-area: footer; - padding: 1rem 1.2rem; - text-align: center; - color: var(--text-muted); - font-size: 0.85rem; - border-top: 1px solid var(--border-color); - background-color: var(--sidebar-bg); /* 使用变量 */ - margin-top: 0; - transition: background-color 0.3s ease, color 0.3s ease; +/* 折叠状态下的内容区域调整 */ +.sidebar.collapsed .sidebar-content { + padding: 0 0.5rem; + scrollbar-width: none; /* 隐藏滚动条 */ } -.copyright a { - color: var(--accent-color); - text-decoration: none; - transition: all 0.3s ease; +.sidebar.collapsed .sidebar-content::-webkit-scrollbar { + display: none; /* 隐藏WebKit浏览器的滚动条 */ } -.copyright a:hover { - color: var(--accent-hover); - text-decoration: underline; -} - -.logo h1 { - font-size: 1.4rem; - color: var(--text-bright); - margin-bottom: 1rem; - padding-left: 0.5rem; - letter-spacing: 0.5px; - transition: color 0.3s ease; +/* 折叠状态下的Logo文本 */ +.sidebar.collapsed .logo h1 { + opacity: 0; + transform: translateX(-20px); + width: 0; + visibility: hidden; /* 确保完全隐藏,防止干扰布局 */ } /* 导航区域样式 */ .nav-section { display: flex; flex-direction: column; - gap: 0.4rem; /* 稍微减小导航项之间的间距 */ + gap: 0.25rem; /* 从0.4rem减小到0.25rem */ } .section-title { font-size: 1rem; color: var(--accent-color); - padding: 0.5rem; - margin-bottom: 0.4rem; /* 稍微减小标题底部边距 */ + padding: 0.4rem 0.5rem; /* 减小上下padding */ + margin-bottom: 0.2rem; /* 从0.4rem减小到0.2rem */ display: flex; align-items: center; gap: 0.5rem; @@ -321,10 +424,66 @@ body.loaded .layout { font-size: 1.2rem; } +/* 调整侧边栏折叠状态下的章节标题 */ +.sidebar.collapsed .section-title { + justify-content: center; + padding: 0.6rem 0 0.3rem; + text-align: center; + margin-bottom: 0.4rem; +} + +.sidebar.collapsed .section-title i { + margin: 0 auto; + font-size: 1.2rem; +} + +/* 折叠状态下的导航项布局优化 */ +.sidebar.collapsed .nav-section { + gap: 0.4rem; + align-items: center; +} + +.sidebar.collapsed .nav-item { + padding: 0.6rem 0; + justify-content: center; + width: 90%; + text-align: center; + margin-left: auto; + margin-right: auto; + /* 调整宽度确保不出现水平滚动条 */ + max-width: calc(var(--sidebar-collapsed-width) - 6px); + box-sizing: border-box; +} + +.sidebar.collapsed .nav-item i { + font-size: 1.25rem; + width: auto; + margin: 0 auto; + padding: 0; +} + +.sidebar.collapsed .nav-item .icon-container { + margin-right: 0; + width: auto; /* 移除固定宽度限制 */ + display: flex; + justify-content: center; + align-items: center; +} + +/* 折叠状态下的导航项文本 */ +.sidebar.collapsed .nav-item .nav-text, +.sidebar.collapsed .nav-item .external-icon { + opacity: 0; + transform: translateX(-10px); + width: 0; + display: none; /* 完全移除,防止干扰布局 */ + visibility: hidden; +} + .nav-item { display: flex; align-items: center; - padding: 0.8rem; + padding: 0.6rem 0.8rem; /* 从0.8rem减小到上下0.6rem,左右保持0.8rem */ color: var(--nav-item-color); text-decoration: none; border-radius: 8px; @@ -338,10 +497,14 @@ body.loaded .layout { justify-content: center; align-items: center; margin-right: 1rem; + transition: margin 0.3s ease; } .nav-item .nav-text { flex: 1; + transition: opacity 0.3s ease, transform 0.3s ease; + white-space: nowrap; + overflow: hidden; } .nav-item .external-icon { @@ -371,24 +534,36 @@ body.loaded .layout { text-align: center; } +/* 折叠状态下的版权区域 */ +.sidebar.collapsed .copyright { + opacity: 0; + visibility: hidden; /* 确保完全隐藏 */ +} + /* 主内容区域 - 修复滚动条问题 */ .content { flex: 1; - margin-left: 240px; + margin-left: var(--sidebar-width); padding: 2rem 1.5rem; background-color: var(--bg-color); position: relative; height: 100vh; /* 固定高度 */ overflow-y: auto; /* 使用auto替代scroll,只在需要时显示滚动条 */ overflow-x: hidden; - max-width: calc(100vw - 240px); + max-width: calc(100vw - var(--sidebar-width)); display: flex; flex-direction: column; align-items: center; /* 应用自定义滚动条样式 */ scrollbar-width: thin; /* Firefox */ scrollbar-color: var(--scrollbar-color) transparent; /* Firefox */ - transition: background-color 0.3s ease; + transition: background-color 0.3s ease, margin-left 0.3s ease, max-width 0.3s ease; +} + +/* 优化内容区域在侧边栏折叠状态下的边距 */ +body .content.expanded { + margin-left: var(--sidebar-collapsed-width); + max-width: calc(100vw - var(--sidebar-collapsed-width)); } .content::-webkit-scrollbar { @@ -934,11 +1109,19 @@ body.loaded .layout { .sidebar { transform: translateX(-100%); box-shadow: none; - transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); + transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), width 0.3s ease; } .sidebar .logo { - padding-top: 3rem; + padding-top: 1.5rem; + display: flex; + align-items: center; + height: 60px; + } + + /* 移动端下隐藏侧边栏折叠按钮 */ + .sidebar-toggle { + display: none; } .sidebar.active { @@ -946,6 +1129,29 @@ body.loaded .layout { box-shadow: 2px 0 10px var(--shadow-color); } + /* 重置移动端下的侧边栏展开状态 */ + .sidebar.collapsed { + width: var(--sidebar-width); + } + + .sidebar.collapsed .logo h1, + .sidebar.collapsed .nav-item .nav-text, + .sidebar.collapsed .nav-item .external-icon, + .sidebar.collapsed .copyright { + opacity: 1; + transform: none; + width: auto; + } + + .sidebar.collapsed .nav-item { + padding: 0.6rem 0.8rem; + justify-content: flex-start; + } + + .sidebar.collapsed .nav-item .icon-container { + margin-right: 1rem; + } + .search-container { position: fixed; top: 0; @@ -1222,4 +1428,28 @@ body.loaded .layout { .sites-grid { transition: gap 0.3s ease; +} + +/* 侧边栏底部区域 - 版权信息 */ +.sidebar .copyright { + grid-area: footer; + padding: 1rem 1.2rem; + text-align: center; + color: var(--text-muted); + font-size: 0.85rem; + border-top: 1px solid var(--border-color); + background-color: var(--sidebar-bg); /* 使用变量 */ + margin-top: 0; + transition: background-color 0.3s ease, color 0.3s ease, opacity 0.3s ease; +} + +.copyright a { + color: var(--accent-color); + text-decoration: none; + transition: all 0.3s ease; +} + +.copyright a:hover { + color: var(--accent-hover); + text-decoration: underline; } \ No newline at end of file diff --git a/src/script.js b/src/script.js index e94a71c..3c56cb1 100644 --- a/src/script.js +++ b/src/script.js @@ -19,6 +19,10 @@ document.addEventListener('DOMContentLoaded', () => { const searchContainer = document.querySelector('.search-container'); const overlay = document.querySelector('.overlay'); + // 侧边栏折叠功能 + const sidebarToggle = document.querySelector('.sidebar-toggle'); + const content = document.querySelector('.content'); + // 主题切换元素 const themeToggle = document.querySelector('.theme-toggle'); const themeIcon = themeToggle.querySelector('i'); @@ -29,6 +33,7 @@ document.addEventListener('DOMContentLoaded', () => { let isSidebarOpen = false; let isSearchOpen = false; let isLightTheme = false; // 主题状态 + let isSidebarCollapsed = false; // 侧边栏折叠状态 // 搜索索引,用于提高搜索效率 let searchIndex = { @@ -36,6 +41,42 @@ document.addEventListener('DOMContentLoaded', () => { items: [] }; + // 侧边栏折叠功能 + function toggleSidebarCollapse() { + isSidebarCollapsed = !isSidebarCollapsed; + + // 使用 requestAnimationFrame 确保平滑过渡 + requestAnimationFrame(() => { + sidebar.classList.toggle('collapsed', isSidebarCollapsed); + content.classList.toggle('expanded', isSidebarCollapsed); + + // 保存折叠状态到localStorage + localStorage.setItem('sidebarCollapsed', isSidebarCollapsed ? 'true' : 'false'); + }); + } + + // 初始化侧边栏折叠状态 + function initSidebarState() { + // 从localStorage获取侧边栏状态 + const savedState = localStorage.getItem('sidebarCollapsed'); + + // 如果有保存状态且不是移动设备,则应用该状态 + if (savedState === 'true' && !isMobile()) { + isSidebarCollapsed = true; + sidebar.classList.add('collapsed'); + content.classList.add('expanded'); + } else { + isSidebarCollapsed = false; + sidebar.classList.remove('collapsed'); + content.classList.remove('expanded'); + } + } + + // 侧边栏折叠按钮点击事件 + if (sidebarToggle) { + sidebarToggle.addEventListener('click', toggleSidebarCollapse); + } + // 主题切换功能 function toggleTheme() { isLightTheme = !isLightTheme; @@ -171,6 +212,10 @@ document.addEventListener('DOMContentLoaded', () => { overlay.classList.remove('active'); isSidebarOpen = false; isSearchOpen = false; + } else { + // 在移动设备下,重置侧边栏折叠状态 + sidebar.classList.remove('collapsed'); + content.classList.remove('expanded'); } }); @@ -534,6 +579,9 @@ document.addEventListener('DOMContentLoaded', () => { // 初始化主题 initTheme(); + // 初始化侧边栏状态 + initSidebarState(); + // 延迟一帧执行初始化,确保样式已经应用 requestAnimationFrame(() => { // 显示首页 diff --git a/templates/index.html b/templates/index.html index 5ecdd44..c41875b 100644 --- a/templates/index.html +++ b/templates/index.html @@ -32,6 +32,9 @@