原生JS主题切换刷新后localStorage存储值错误排查
本地存储主题切换故障排查
核心错误原因
一共4个逻辑漏洞共同导致故障:
- 大小写拼写错误:存储folder值时调用的是
setfolder()(f小写),但实际定义的函数名是setFolder()(F大写),该行代码直接抛出JS异常,folder值从未被正确存入localStorage。 - 函数参数逻辑缺失:
setFolder()没有设计入参处理逻辑,无论什么时候调用,都只会读取当前下拉选框选中项的data-id值。页面刷新初始状态下,下拉框默认选中HTML里硬编码selected的cyberpunk选项,此时调用setFolder()永远返回gusbemacbe,根本无法读取之前存储的folder值。 - 初始化顺序错误:页面加载执行
getTheme()时,先调用setTheme(theme)拼接CSS路径,此时下拉框还停留在默认的cyberpunk选项,拼出来的路径自然是gusbemacbe/[存储的theme名].css;后续调用setFolder(folder)虽然传了存储的folder值,但函数根本不接收参数,执行完全无效,也没有同步下拉框的选中状态。 - 重复事件绑定:select标签上写了内联
onchange="setFolder()",JS里又通过addEventListener绑定了change事件,冗余逻辑容易引发不可预期的执行顺序问题。
修复步骤
1. 修改HTML代码
去掉select上冗余的内联onchange事件,去掉option上硬编码的selected属性(选中状态后续由JS初始化时根据localStorage值同步):
<!-- 主题样式表引入 --> <link rel="stylesheet" media="screen" type="text/css" href="assets/css/tokens/gusbemacbe/cyberpunk.css" id="active_stylesheet"> <!-- 主题选择下拉框 --> <select id="ThemeSelect"> <option data-id="gusbemacbe" value="cyberpunk">cyberpunk</option> <option data-id="voxel" value="ion">íon</option> <option data-id="voxel" value="itau">itaú</option> <option data-id="voxel" value="iti">iti</option> </select> <script src="assets/js/global.js"></script>
2. 重写JS逻辑
调整函数职责,修正初始化顺序,确保存储值、下拉选中状态、样式路径三者完全同步:
// 切换样式表路径 function changeCSS(sheet) { document.getElementById('active_stylesheet').setAttribute('href', sheet); } // 保存选中主题到本地存储并切换样式 function saveAndApplyTheme(folder, theme) { // 拼接正确的CSS路径 const cssPath = `assets/css/tokens/${folder}/${theme}.css`; changeCSS(cssPath); // 两个值同时存储,避免不一致 localStorage.setItem('folder', folder); localStorage.setItem('theme', theme); } // 监听下拉框选择事件 const themeSelect = document.getElementById("ThemeSelect"); themeSelect.addEventListener('change', function () { const selectedOption = this.options[this.selectedIndex]; const folder = selectedOption.getAttribute("data-id"); const theme = selectedOption.value; saveAndApplyTheme(folder, theme); }); // 页面初始化:读取本地存储同步状态 function initTheme() { const storedFolder = localStorage.getItem('folder'); const storedTheme = localStorage.getItem('theme'); // 没有存储值时用默认主题 if (!storedFolder || !storedTheme) { saveAndApplyTheme('gusbemacbe', 'cyberpunk'); return; } // 先同步下拉框选中状态 for (let i = 0; i < themeSelect.options.length; i++) { const option = themeSelect.options[i]; if (option.value === storedTheme && option.getAttribute("data-id") === storedFolder) { option.selected = true; break; } } // 再应用存储的主题 saveAndApplyTheme(storedFolder, storedTheme); } // 执行初始化 initTheme();
修复验证
修复后选择voxel文件夹下的íon主题,刷新页面将符合预期:
- 下拉选框默认选中íon选项
- 样式路径正确加载为
assets/css/tokens/voxel/ion.css - localStorage中存储的folder值为
voxel、theme值为ion,不会再出现值不匹配的问题
内容的提问来源于stack exchange,提问作者Oo'-
相关产品推荐
相关产品推荐

