修复主题切换闪烁问题

This commit is contained in:
Zuoling Rong
2025-05-03 13:34:22 +08:00
parent 867d5d8adf
commit e97fb43159
3 changed files with 100 additions and 43 deletions

View File

@@ -55,6 +55,30 @@ body.light-theme {
--gradient-color-simple: linear-gradient(135deg, #4a9eff 0%, #a855f7 100%);
}
/* 预加载主题 - 在JS完全加载前显示正确的主题 */
html.theme-preload body {
background-color: #e0e0d8; /* 明亮主题背景色 */
color: #333333; /* 明亮主题文本色 */
}
/* 预加载侧边栏状态 - 在JS完全加载前显示正确的侧边栏宽度 */
html.sidebar-collapsed-preload .sidebar {
width: var(--sidebar-collapsed-width);
}
html.sidebar-collapsed-preload .content {
margin-left: var(--sidebar-collapsed-width);
}
/* 控制页面预加载状态 */
html.preload .layout {
opacity: 0;
}
html.preload * {
transition: none !important;
}
/* 主题切换按钮 */
.theme-toggle {
position: fixed;

View File

@@ -1,8 +1,20 @@
document.addEventListener('DOMContentLoaded', () => {
// 即时移除loading类确保侧边栏可见
document.body.classList.remove('loading');
document.body.classList.add('loaded');
// 先声明所有状态变量
let isSearchActive = false;
let currentPageId = 'home';
let isInitialLoad = true;
let isSidebarOpen = false;
let isSearchOpen = false;
let isLightTheme = false; // 主题状态
let isSidebarCollapsed = false; // 侧边栏折叠状态
// 搜索索引,用于提高搜索效率
let searchIndex = {
initialized: false,
items: []
};
// 获取DOM元素
const searchInput = document.getElementById('search');
const siteCards = document.querySelectorAll('.site-card');
const categories = document.querySelectorAll('.category');
@@ -27,19 +39,27 @@ document.addEventListener('DOMContentLoaded', () => {
const themeToggle = document.querySelector('.theme-toggle');
const themeIcon = themeToggle.querySelector('i');
let isSearchActive = false;
let currentPageId = 'home';
let isInitialLoad = true;
let isSidebarOpen = false;
let isSearchOpen = false;
let isLightTheme = false; // 主题状态
let isSidebarCollapsed = false; // 侧边栏折叠状态
// 移除预加载类允许CSS过渡效果
document.documentElement.classList.remove('preload');
// 搜索索引,用于提高搜索效率
let searchIndex = {
initialized: false,
items: []
};
// 应用从localStorage读取的主题设置
if (document.documentElement.classList.contains('theme-preload')) {
document.documentElement.classList.remove('theme-preload');
document.body.classList.add('light-theme');
isLightTheme = true;
}
// 应用从localStorage读取的侧边栏状态
if (document.documentElement.classList.contains('sidebar-collapsed-preload')) {
document.documentElement.classList.remove('sidebar-collapsed-preload');
sidebar.classList.add('collapsed');
content.classList.add('expanded');
isSidebarCollapsed = true;
}
// 即时移除loading类确保侧边栏可见
document.body.classList.remove('loading');
document.body.classList.add('loaded');
// 侧边栏折叠功能
function toggleSidebarCollapse() {
@@ -55,20 +75,16 @@ document.addEventListener('DOMContentLoaded', () => {
});
}
// 初始化侧边栏折叠状态
// 初始化侧边栏折叠状态 - 已在页面加载前处理,此处仅完成图标状态初始化等次要任务
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');
}
}
@@ -95,19 +111,18 @@ document.addEventListener('DOMContentLoaded', () => {
localStorage.setItem('theme', isLightTheme ? 'light' : 'dark');
}
// 初始化主题
// 初始化主题 - 已在页面加载前处理,此处仅完成图标状态初始化等次要任务
function initTheme() {
// 从localStorage获取主题偏好
const savedTheme = localStorage.getItem('theme');
// 更新图标状态以匹配当前主题
if (savedTheme === 'light') {
isLightTheme = true;
document.body.classList.add('light-theme');
themeIcon.classList.remove('fa-moon');
themeIcon.classList.add('fa-sun');
} else {
isLightTheme = false;
document.body.classList.remove('light-theme');
themeIcon.classList.remove('fa-sun');
themeIcon.classList.add('fa-moon');
}
@@ -587,24 +602,22 @@ document.addEventListener('DOMContentLoaded', () => {
// 初始化侧边栏状态
initSidebarState();
// 延迟一帧执行初始化,确保样式已经应用
requestAnimationFrame(() => {
// 显示首页
showPage('home');
// 立即执行初始化,不再使用requestAnimationFrame延迟
// 显示首页
showPage('home');
// 添加载入动画
categories.forEach((category, index) => {
setTimeout(() => {
category.style.opacity = '1';
}, index * 100);
});
// 初始化搜索索引使用requestIdleCallback或setTimeout延迟初始化避免影响页面加载
if ('requestIdleCallback' in window) {
requestIdleCallback(() => initSearchIndex());
} else {
setTimeout(initSearchIndex, 1000);
}
// 添加载入动画
categories.forEach((category, index) => {
setTimeout(() => {
category.style.opacity = '1';
}, index * 100);
});
// 初始化搜索索引使用requestIdleCallback或setTimeout延迟初始化避免影响页面加载
if ('requestIdleCallback' in window) {
requestIdleCallback(() => initSearchIndex());
} else {
setTimeout(initSearchIndex, 1000);
}
});
});

View File

@@ -10,10 +10,30 @@
<style>
{{{FONT_VARIABLES}}}
</style>
<!-- 预设主题和侧边栏状态,避免闪烁 -->
<script>
(function() {
// 读取并应用主题设置
var savedTheme = localStorage.getItem('theme');
if (savedTheme === 'light') {
document.documentElement.classList.add('theme-preload');
}
// 读取并应用侧边栏状态
var sidebarCollapsed = localStorage.getItem('sidebarCollapsed') === 'true';
var isMobile = window.innerWidth <= 768;
if (sidebarCollapsed && !isMobile) {
document.documentElement.classList.add('sidebar-collapsed-preload');
}
// 添加这个类用于控制初始渲染
document.documentElement.classList.add('preload');
})();
</script>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
</head>
<body class="loaded">
<body class="loading">
<div class="layout">
<!-- 移动端按钮 -->
<div class="mobile-buttons">