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

基于Bootstrap 5实现页面加载及主题切换时单选按钮自动选中

解决Bootstrap 5主题切换时单选按钮同步选中状态的问题

问题背景

使用Bootstrap 5官方提供的暗色模式切换JavaScript代码时,页面加载或切换主题时,对应的单选按钮无法自动同步checked状态——默认只有Light按钮被标记为checked,即使本地存储了其他主题也不会自动切换选中项。

修改方案

需要修改showActiveTheme函数,在处理样式类的同时,同步设置单选按钮的checked属性:

const showActiveTheme = (theme, focus = false) => {
  const themeSwitcher = document.querySelector('#bd-theme')

  if (!themeSwitcher) {
    return
  }

  // 获取对应主题的单选按钮
  const btnToActive = document.querySelector(`[data-bs-theme-value="${theme}"]`)

  // 重置所有单选按钮的选中状态和样式类
  document.querySelectorAll('[data-bs-theme-value]').forEach(element => {
    element.classList.remove('checked')
    element.checked = false
  })

  // 设置目标按钮的选中状态和样式类
  btnToActive.classList.add('checked')
  btnToActive.checked = true

  if (focus) {
    themeSwitcher.focus()
  }
}

修改说明

  1. 遍历所有主题切换按钮时,新增element.checked = false,统一重置选中状态
  2. 找到目标主题按钮后,新增btnToActive.checked = true,设置其为选中状态
  3. 保留原有的样式类操作,确保Bootstrap按钮组的视觉选中效果正常

完整修改后的JavaScript代码

(() => {
  'use strict'

  const getStoredTheme = () => localStorage.getItem('theme')
  const setStoredTheme = theme => localStorage.setItem('theme', theme)

  const getPreferredTheme = () => {
    const storedTheme = getStoredTheme()
    if (storedTheme) {
      return storedTheme
    }

    return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'
  }

  const setTheme = theme => {
    if (theme === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches) {
      document.documentElement.setAttribute('data-bs-theme', 'dark')
    } else {
      document.documentElement.setAttribute('data-bs-theme', theme)
    }
  }

  setTheme(getPreferredTheme())

  const showActiveTheme = (theme, focus = false) => {
    const themeSwitcher = document.querySelector('#bd-theme')

    if (!themeSwitcher) {
      return
    }

    const btnToActive = document.querySelector(`[data-bs-theme-value="${theme}"]`)

    document.querySelectorAll('[data-bs-theme-value]').forEach(element => {
      element.classList.remove('checked')
      element.checked = false
    })

    btnToActive.classList.add('checked')
    btnToActive.checked = true

    if (focus) {
      themeSwitcher.focus()
    }
  }

  window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => {
    const storedTheme = getStoredTheme()
    if (storedTheme !== 'light' && storedTheme !== 'dark') {
      setTheme(getPreferredTheme())
    }
  })

  window.addEventListener('DOMContentLoaded', () => {
    showActiveTheme(getPreferredTheme())

    document.querySelectorAll('[data-bs-theme-value]')
      .forEach(toggle => {
        toggle.addEventListener('click', () => {
          const theme = toggle.getAttribute('data-bs-theme-value')
          setStoredTheme(theme)
          setTheme(theme)
          showActiveTheme(theme, true)
        })
      })
  })
})()

配套HTML按钮组说明

建议移除默认的checked属性,让JavaScript自动根据存储的主题或系统偏好设置选中项:

<div class="btn-group" id="bd-theme" role="group">
  <input autocomplete="off" class="btn-check" data-bs-theme-value="light" id="btnradio1" name="btnradio" type="radio">
  <label class="btn btn-outline-dark" for="btnradio1">
    Light
  </label>
  <input autocomplete="off" class="btn-check" data-bs-theme-value="dark" id="btnradio2" name="btnradio" type="radio">
  <label class="btn btn-outline-dark" for="btnradio2">
    Dark
  </label>
  <input autocomplete="off" class="btn-check" data-bs-theme-value="auto" id="btnradio3" name="btnradio" type="radio">
  <label class="btn btn-outline-dark" for="btnradio3">
    Auto
  </label>
</div>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 23:00:04