
通过 localstorage 在页面加载时读取并应用用户上次选择的主题模式,配合 css 类切换实现刷新不丢失的暗色/亮色主题功能。
在 Web 开发中,实现“刷新不丢失主题设置”是提升用户体验的关键细节。核心思路是:将用户选择的主题状态(如 'light' 或 'dark')持久化存储于浏览器端,并在每次页面加载时主动读取、应用该状态。localStorage 是最常用且合适的方案——它不随页面刷新清除,且无需服务端参与。
以下是一个完整、可直接运行的实现示例:
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>主题持久化示例</title>
<style>
/* 默认为亮色主题(无 class 时生效) */
body {
background-color: #ffffff;
color: #000000;
margin: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
transition: background-color 0.3s, color 0.3s;
}
/* 暗色主题样式 */
body.dark {
background-color: #222222;
color: #ffffff;
}
.theme-toggle {
position: fixed;
top: 20px;
right: 20px;
padding: 10px 16px;
background: #007bff;
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
font-size: 14px;
}
.theme-toggle:hover {
background: #0056b3;
}
</style>
</head>
<body>
<button id="theme-toggle" class="theme-toggle">? 切换主题</button>
<script>
const themeToggle = document.getElementById('theme-toggle');
const body = document.body;
// 点击切换主题
themeToggle.addEventListener('click', () => {
body.classList.toggle('dark');
// 同步更新 localStorage
const currentTheme = body.classList.contains('dark') ? 'dark' : 'light';
localStorage.setItem('theme', currentTheme);
});
// 页面加载时恢复主题
const savedTheme = localStorage.getItem('theme');
if (savedTheme === 'dark') {
body.classList.add('dark');
} else {
body.classList.remove('dark'); // 确保 light 主题干净启用
}
</script>
</body>
</html>✅ 关键要点说明:
- 时机准确:localStorage.getItem() 必须在 DOM 加载完成(如 <script> 放在 </body> 前)后立即执行,确保 body 可操作;
- 状态同步:不仅点击时存,还要在切换后实时更新 localStorage,避免因异常中断导致状态错位;
- CSS 过渡增强体验:添加 transition 属性使背景/文字颜色变化更平滑;
- 防御性处理:localStorage.getItem() 可能返回 null,因此使用严格相等判断(=== 'dark'),未命中时默认走亮色逻辑;
- 无障碍友好:按钮含语义化文本(如“? 切换主题”),支持键盘操作与屏幕阅读器。
? 进阶建议:
- 结合 prefers-color-scheme 媒体查询,在首次访问时自动适配系统偏好;
- 使用 matchMedia 监听系统主题变更,动态响应(需额外逻辑);
- 将逻辑封装为可复用的 useTheme() Hook(React)或自定义函数,便于项目扩展。
只要正确写入并读取 localStorage,用户无论刷新、关闭再打开,甚至跨会话访问,主题偏好都将被可靠保留。










