You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决四季主题切换时body类名叠加、事件监听器堆叠的问题

问题根源
  • 原代码每个季节的点击事件仅对当前主题类执行toggle操作,没有清除其他季节的主题类,导致类名叠加
  • 多份独立的sessionStorage存储逻辑冗余,也容易出现状态不一致的问题
修复方案

轻量改法(无需重构现有代码)

如果不想改动原有代码结构,只需要在每个季节的点击事件最开头,先移除另外三个季节的主题类,把toggle改成add即可,以春季逻辑为例修改后:

//spring change
springIcon.addEventListener('click', () => {
    // 新增:先移除其他三个季节的主题类
    document.body.classList.remove('summer-theme', 'autumn-theme', 'winter-theme');
    // 把toggle改为add,直接启用春季主题不需要判断原有状态
    document.body.classList.add('spring-theme');
    spring.classList.add('show-icon');
    summer.classList.remove('show-icon');
    autumn.classList.remove('show-icon');
    winter.classList.remove('show-icon');
    // 存储逻辑可以简化为直接存true,其他季节的存储值点击对应图标时再改即可
    sessionStorage.setItem("spring-theme", "true")
    sessionStorage.setItem("summer-theme", "false")
    sessionStorage.setItem("autumn-theme", "false")
    sessionStorage.setItem("winter-theme", "false")
})

其余三个季节的逻辑按照相同规则修改即可,不会影响body上原有的固定类名(比如你示例里的b-page)。


优化改法(抽离公共逻辑减少冗余)

如果希望减少重复代码,后期维护更方便,可以把四季的公共逻辑统一管理:

// 统一配置所有主题信息
const themes = [
  { name: 'spring', icon: springIcon },
  { name: 'summer', icon: summerIcon },
  { name: 'autumn', icon: autumnIcon },
  { name: 'winter', icon: winterIcon }
]
const themeClassList = themes.map(t => `${t.name}-theme`)

// 页面初始化时读取存储的主题加载对应样式
const activeTheme = sessionStorage.getItem('activeTheme')
if (activeTheme) {
  document.body.classList.remove(...themeClassList)
  document.body.classList.add(`${activeTheme}-theme`)
  themes.forEach(t => {
    t.icon.classList.toggle('show-icon', t.name === activeTheme)
    t.icon.classList.toggle('hide-icon', t.name !== activeTheme)
  })
}

// 统一绑定点击事件
themes.forEach(theme => {
  theme.icon.addEventListener('click', () => {
    // 清除所有主题类后添加当前选中的主题
    document.body.classList.remove(...themeClassList)
    document.body.classList.add(`${theme.name}-theme`)
    // 统一处理图标显隐
    themes.forEach(t => {
      t.icon.classList.toggle('show-icon', t.name === theme.name)
      t.icon.classList.toggle('hide-icon', t.name !== theme.name)
    })
    // 仅用一个字段存储当前选中的主题,无需维护4个存储变量
    sessionStorage.setItem('activeTheme', theme.name)
  })
})

内容的提问来源于stack exchange,提问作者Rach

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 08:15:00