页面切换时保留JS设置网站主题的问题求助
主题切换脚本修复方案
问题概述
编写了JS主题切换脚本,期望页面跳转时保留当前主题,但sessionStorage恢复主题逻辑失效,setupPage函数无法触发调试alert。
原代码
var theme = "dark"; var themeProperties = ['--bodybgcolor', '--breadcrumbbg', '--navbarbg', '--txtcolor', '--linkcolor', '--linkvisited', '--linkhovercolor', '--navlinkcolor', '--navlinkvisited', '--navlinkhovercolor', '--navlinkbg', '--themebg', '--themeborder', '--iconpos', '--logo', '--cardbg', '--cardLogobg', '--cardshadow', '--cardtxtcolor', '--breadcrumbsvg']; var themeValues = [['#050505', '#181818', '#050505', '#f1f1f1', '#f1f1f1', '#f1f1f1', '#1BDC88', '#f1f1f1', '#f1f1f1', '#1BDC88', '#5050504d', '#f1f1f1', '#1BDC88', 'left', 'url(../img/logo-sfondo-nero.webp)', '#181818', '#ffffff', '#141414', '#f1f1f1', 'invert(100%) sepia(100%) saturate(0%) hue-rotate(302deg) brightness(101%) contrast(102%)'], ['#ffffff', '#f1f1f1', '#ffffff', '#000000', '#000000', '#000000', '#1BDC88', '#000000', '#000000', '#1BDC88', '#ababab4d', '#000000', '#1BDC88', 'right', 'url(../img/logo-sfondo-bianco.webp)', '#ededed', '#e1e1e1', '#e1e1e1', '#000000', 'invert(0%) sepia(97%) saturate(14%) hue-rotate(160deg) brightness(103%) contrast(102%)']]; window.readyState(setupWindow()); document.readyState(setupPage()); function setupWindow() { sessionStorage.setItem('panelTheme', theme); } function setupPage() { alert(sessionStorage.getItem('panelTheme'));/*this was for debugging in order to know if it was run or not*/ } function changeTheme() { localstTheme = sessionStorage.getItem('panelTheme'); if (localstTheme == 'dark') { theme = 'light'; setTheme('light'); } else { theme = 'dark'; setTheme('dark'); } } function setTheme(theme) { if (theme == 'dark') { sessionStorage.setItem('panelTheme', theme); for (var i = 0; i < themeProperties.length; i++) { document.documentElement.style.setProperty(themeProperties[i], themeValues[0][i]); } } if (theme == 'light') { sessionStorage.setItem('panelTheme', theme); for (var i = 0; i < themeProperties.length; i++) { document.documentElement.style.setProperty(themeProperties[i], themeValues[1][i]); }/**/ } }
核心问题分析
- 页面加载触发方式错误:
window.readyState和document.readyState是只读属性,不能作为方法调用执行函数,导致setupWindow和setupPage未正确触发。 - 初始化逻辑顺序错误:页面加载时直接设置默认主题到sessionStorage,未读取已有保存值,导致页面跳转后丢失之前切换的主题。
- 变量未规范声明:
localstTheme未用var/let/const声明,会成为全局变量,存在潜在风险。
修复后的代码
// 主题配置常量 const themeProperties = ['--bodybgcolor', '--breadcrumbbg', '--navbarbg', '--txtcolor', '--linkcolor', '--linkvisited', '--linkhovercolor', '--navlinkcolor', '--navlinkvisited', '--navlinkhovercolor', '--navlinkbg', '--themebg', '--themeborder', '--iconpos', '--logo', '--cardbg', '--cardLogobg', '--cardshadow', '--cardtxtcolor', '--breadcrumbsvg']; const themeValues = [ ['#050505', '#181818', '#050505', '#f1f1f1', '#f1f1f1', '#f1f1f1', '#1BDC88', '#f1f1f1', '#f1f1f1', '#1BDC88', '#5050504d', '#f1f1f1', '#1BDC88', 'left', 'url(../img/logo-sfondo-nero.webp)', '#181818', '#ffffff', '#141414', '#f1f1f1', 'invert(100%) sepia(100%) saturate(0%) hue-rotate(302deg) brightness(101%) contrast(102%)'], ['#ffffff', '#f1f1f1', '#ffffff', '#000000', '#000000', '#000000', '#1BDC88', '#000000', '#000000', '#1BDC88', '#ababab4d', '#000000', '#1BDC88', 'right', 'url(../img/logo-sfondo-bianco.webp)', '#ededed', '#e1e1e1', '#e1e1e1', '#000000', 'invert(0%) sepia(97%) saturate(14%) hue-rotate(160deg) brightness(103%) contrast(102%)'] ]; // 页面DOM加载完成后初始化主题 document.addEventListener('DOMContentLoaded', initTheme); // 初始化主题:优先读取sessionStorage,无则用默认dark function initTheme() { const savedTheme = sessionStorage.getItem('panelTheme') || 'dark'; setTheme(savedTheme); } // 切换主题函数 function changeTheme() { const currentTheme = sessionStorage.getItem('panelTheme') || 'dark'; const newTheme = currentTheme === 'dark' ? 'light' : 'dark'; setTheme(newTheme); } // 应用主题样式 function setTheme(theme) { // 保存主题到sessionStorage sessionStorage.setItem('panelTheme', theme); // 获取对应主题的样式索引 const themeIndex = theme === 'dark' ? 0 : 1; // 批量设置CSS变量 for (let i = 0; i < themeProperties.length; i++) { document.documentElement.style.setProperty(themeProperties[i], themeValues[themeIndex][i]); } }
修复要点说明
- 正确监听页面加载:使用
DOMContentLoaded事件确保DOM完全就绪后执行主题初始化,避免操作未加载完成的元素。 - 优化主题初始化逻辑:页面加载时先读取sessionStorage中保存的主题,没有则使用默认的
dark主题,确保页面跳转后主题状态保留。 - 简化主题应用代码:通过索引直接匹配对应主题的样式数组,减少重复的条件判断代码。
- 规范变量声明:使用
const声明常量、let/const声明局部变量,避免全局变量污染。
内容的提问来源于stack exchange,提问作者Gabriele Da Re
相关产品推荐
相关产品推荐

