Files

103 lines
2.8 KiB
JavaScript
Raw Permalink Normal View History

/**
* 暗黑主题切换功能
* 小白制作 🐶
*/
(function() {
'use strict';
const themeKey = 'my_one_web_theme';
// 获取保存的主题
function getSavedTheme() {
try {
return localStorage.getItem(themeKey) || 'light';
} catch (e) {
return 'light';
}
}
// 保存主题
function saveTheme(theme) {
try {
localStorage.setItem(themeKey, theme);
} catch (e) {
// localStorage 不可用时忽略
}
}
// 应用主题
function applyTheme(theme) {
document.documentElement.setAttribute('data-theme', theme);
updateToggleButton(theme);
}
// 更新切换按钮图标
function updateToggleButton(theme) {
const btn = document.querySelector('.theme-toggle');
if (btn) {
btn.textContent = theme === 'dark' ? '☀️' : '🌙';
btn.setAttribute('aria-label', theme === 'dark' ? '切换到亮色模式' : '切换到暗黑模式');
}
}
// 切换主题(防抖)
let isToggling = false;
function toggleTheme(e) {
// 阻止默认行为和冒泡
if (e) {
e.preventDefault();
e.stopPropagation();
}
// 防抖300ms 内只响应一次
if (isToggling) return;
isToggling = true;
const currentTheme = getSavedTheme();
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
saveTheme(newTheme);
applyTheme(newTheme);
// 300ms 后重置
setTimeout(function() {
isToggling = false;
}, 300);
}
// 初始化主题
function initTheme() {
const savedTheme = getSavedTheme();
applyTheme(savedTheme);
// 绑定切换按钮事件
const btn = document.querySelector('.theme-toggle');
if (btn) {
// 点击事件
btn.addEventListener('click', toggleTheme);
// 触摸事件(移动端)
btn.addEventListener('touchstart', function(e) {
e.preventDefault();
}, { passive: false });
btn.addEventListener('touchend', toggleTheme, { passive: true });
// 键盘支持(无障碍)
btn.addEventListener('keydown', function(e) {
if (e.key === 'Enter' || e.key === ' ') {
e.preventDefault();
toggleTheme(e);
}
});
}
}
// DOM 加载完成后初始化
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', initTheme);
} else {
initTheme();
}
})();