需求背景
在开发基于Hexo的博客网站时,我发现了一个用户体验问题:无论访问网站的时间是白天还是夜间,系统总是默认显示日间模式的图片,即使系统设置为深色模式或当前时间是夜间。这导致必须手动切换主题才能看到与当前主题匹配的图片。
方案设计
- 配置文件增强
- 主题初始化逻辑优化
- 图片加载逻辑改进
- 主题变化事件监听机制
1. 配置文件增强
在主题配置文件(_config.yml)中,添加了两个关键设置选项:
theme_settings: is_dark: false auto_dark: true
|
这些设置允许:
- 网站可以默认以深色模式加载(通过设置
is_dark: true) - 网站可以自动跟随系统主题设置(通过设置
auto_dark: true)
2. 主题初始化逻辑优化
优化了layout.ejs中的主题初始化脚本,使其根据以下优先级确定要使用的主题:
- 之前手动设置的主题(存储在localStorage中)
- 如果启用了自动主题功能且没有设置,则根据系统主题偏好
- 如果上述条件都不满足,则使用配置文件中指定的默认主题
function initTheme() { const configIsDark = theme.theme_settings && theme.theme_settings.is_dark; const configAutoDark = theme.theme_settings && theme.theme_settings.auto_dark; const savedThemePreference = localStorage.getItem('themePreference') || 'auto'; let theme = localStorage.getItem('theme'); if (!theme) { if (configAutoDark) { const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches; theme = prefersDark ? 'dark' : 'light'; } else { theme = configIsDark ? 'dark' : 'light'; } localStorage.setItem('theme', theme); } document.documentElement.setAttribute('data-theme', theme); }
|
3. 图片加载逻辑改进
我修改了index.ejs文件中图片的初始加载逻辑,确保根据当前主题设置显示正确的图片:
<img src="<% if(theme.theme_settings && (theme.theme_settings.is_dark || (theme.theme_settings.auto_dark && window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches))) { %><%= theme.banner_images.top_banner.dark %><% } else { %><%= theme.banner_images.top_banner.light %><% } %>" alt="Banner Background" class="top-banner-image">
|
这段代码会根据当前的主题设置(is_dark)或系统设置(如果启用了auto_dark)选择显示深色或浅色图片。
4. 动态图片更新函数
实现了一个updateImagesBasedOnTheme()函数,负责在主题变化时更新图片:
function updateImagesBasedOnTheme() { const currentTheme = document.documentElement.getAttribute('data-theme'); const isDarkMode = currentTheme === 'dark'; const topBannerImage = document.querySelector('.top-banner-image'); const contentBannerImage = document.getElementById('banner-random-image'); if (topBannerImage) { topBannerImage.src = isDarkMode ? theme.banner_images.top_banner.dark : theme.banner_images.top_banner.light; } if (contentBannerImage) { contentBannerImage.src = isDarkMode ? theme.banner_images.content_banner.dark : theme.banner_images.content_banner.light; } }
|
5. 事件监听机制
添加了事件监听器,以响应主题变化和系统主题变化:
updateImagesBasedOnTheme();
document.addEventListener('themeChanged', function(event) { updateImagesBasedOnTheme(); });
if (theme.theme_settings && theme.theme_settings.auto_dark) { window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', function(e) { if (localStorage.getItem('themePreference') === 'auto') { updateImagesBasedOnTheme(); } }); }
|
实施效果
通过这些优化,成功实现了以下效果:
- 智能初始加载 - 网站会根据用户的系统设置或偏好自动选择合适的主题和图片
- 实时响应 - 当手动切换主题或系统主题发生变化时,图片会立即更新
总结
通过将图片URL集中管理在配置文件中,我也简化了未来的维护工作。当需要更新网站图片时,只需修改配置文件中的URL,而无需修改代码。