63 lines
1.7 KiB
JavaScript
63 lines
1.7 KiB
JavaScript
class ThemeManager {
|
|
constructor() {
|
|
this.theme = this.getStoredTheme() || this.getSystemTheme();
|
|
this.init();
|
|
}
|
|
|
|
init() {
|
|
this.applyTheme(this.theme);
|
|
this.bindEvents();
|
|
}
|
|
|
|
getStoredTheme() {
|
|
return localStorage.getItem('theme');
|
|
}
|
|
|
|
getSystemTheme() {
|
|
return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
|
|
}
|
|
|
|
applyTheme(theme) {
|
|
document.documentElement.setAttribute('data-theme', theme);
|
|
this.updateThemeIcon(theme);
|
|
localStorage.setItem('theme', theme);
|
|
}
|
|
|
|
updateThemeIcon(theme) {
|
|
const themeIcon = document.querySelector('.theme-icon');
|
|
if (themeIcon) {
|
|
themeIcon.textContent = theme === 'dark' ? '☀️' : '🌙';
|
|
}
|
|
}
|
|
|
|
toggleTheme() {
|
|
this.theme = this.theme === 'light' ? 'dark' : 'light';
|
|
this.applyTheme(this.theme);
|
|
this.setCookie('theme', this.theme, 365);
|
|
}
|
|
|
|
setCookie(name, value, days) {
|
|
const expires = new Date();
|
|
expires.setTime(expires.getTime() + (days * 24 * 60 * 60 * 1000));
|
|
document.cookie = `${name}=${value};expires=${expires.toUTCString()};path=/`;
|
|
}
|
|
|
|
bindEvents() {
|
|
const themeToggle = document.getElementById('theme-toggle');
|
|
if (themeToggle) {
|
|
themeToggle.addEventListener('click', () => this.toggleTheme());
|
|
}
|
|
|
|
window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => {
|
|
if (!this.getStoredTheme()) {
|
|
this.theme = e.matches ? 'dark' : 'light';
|
|
this.applyTheme(this.theme);
|
|
}
|
|
});
|
|
}
|
|
}
|
|
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
new ThemeManager();
|
|
});
|