69 lines
2.7 KiB
JavaScript
69 lines
2.7 KiB
JavaScript
/**
|
||
* 主题切换逻辑
|
||
* 依赖: Bootstrap 5.3+ (用于 data-bs-theme 和 Tooltip)
|
||
*/
|
||
document.addEventListener('DOMContentLoaded', function () {
|
||
const toggleBtn = document.getElementById('theme-toggle-btn');
|
||
if (!toggleBtn) return;
|
||
|
||
const htmlElement = document.documentElement;
|
||
|
||
// 初始化 Bootstrap Tooltip
|
||
const tooltip = new bootstrap.Tooltip(toggleBtn);
|
||
|
||
/**
|
||
* 更新按钮的图标和提示文字
|
||
* @param {string} theme - 'light' or 'dark'
|
||
*/
|
||
function updateButtonUI(theme) {
|
||
const iconContainer = toggleBtn.querySelector('i');
|
||
if (!iconContainer) return;
|
||
|
||
if (theme === 'dark') {
|
||
// 当前是深色,按钮显示“太阳”,提示“切换到浅色”
|
||
iconContainer.className = 'bi bi-sun-fill';
|
||
toggleBtn.setAttribute('data-bs-original-title', '切换到浅色模式');
|
||
} else {
|
||
// 当前是浅色,按钮显示“月亮”,提示“切换到深色”
|
||
iconContainer.className = 'bi bi-moon-stars-fill';
|
||
toggleBtn.setAttribute('data-bs-original-title', '切换到深色模式');
|
||
}
|
||
|
||
// 刷新 Tooltip 显示
|
||
tooltip.setContent({ '.tooltip-inner': toggleBtn.getAttribute('data-bs-original-title') });
|
||
}
|
||
|
||
// 初始更新 UI (确保图标与后端传来的 ViewBag.CurrentTheme 一致)
|
||
// 注意:data-bs-theme 已经在 HTML 根节点由 Razor 设置
|
||
const initialTheme = htmlElement.getAttribute('data-bs-theme') || 'light';
|
||
updateButtonUI(initialTheme);
|
||
|
||
// 点击事件处理
|
||
toggleBtn.addEventListener('click', function () {
|
||
const currentTheme = htmlElement.getAttribute('data-bs-theme');
|
||
const newTheme = currentTheme === 'dark' ? 'light' : 'dark';
|
||
|
||
// 1. 立即更新 UI (无刷新)
|
||
htmlElement.setAttribute('data-bs-theme', newTheme);
|
||
updateButtonUI(newTheme);
|
||
tooltip.show(); // 可选:点击时短暂显示提示
|
||
setTimeout(() => tooltip.hide(), 1000);
|
||
|
||
// 2. 异步持久化到后端
|
||
fetch('/Home/SetTheme', {
|
||
method: 'POST',
|
||
headers: {
|
||
'Content-Type': 'application/json',
|
||
// 如果需要 AntiForgery Token,请确保页面中有表单或手动注入
|
||
// 'RequestVerificationToken': document.querySelector('input[name="__RequestVerificationToken"]')?.value
|
||
},
|
||
body: JSON.stringify({ theme: newTheme })
|
||
})
|
||
.then(response => {
|
||
if (!response.ok) {
|
||
console.error('Failed to save theme preference');
|
||
}
|
||
})
|
||
.catch(error => console.error('Error:', error));
|
||
});
|
||
}); |