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

实现Tailwind Darkmode:支持系统偏好与手动切换

暗黑模式适配系统偏好+手动切换解决方案

原代码存在两个核心问题:初始化时未给系统暗色偏好的场景添加dark类,且未监听系统配色偏好的变化事件,导致无法自动跟随系统主题切换。以下是修复后的完整实现:

修复后的JS代码

// 暗黑/亮色模式切换
const themeToggleDarkIcon = document.getElementById('moon');
const themeToggleLightIcon = document.getElementById('sun');
const themeToggleBtn = document.getElementById('theme-toggle');
const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');

// 统一更新主题状态的函数
function updateTheme(isDark) {
  if (isDark) {
    document.documentElement.classList.add('dark');
    themeToggleLightIcon.classList.remove('hidden');
    themeToggleDarkIcon.classList.add('hidden');
  } else {
    document.documentElement.classList.remove('dark');
    themeToggleDarkIcon.classList.remove('hidden');
    themeToggleLightIcon.classList.add('hidden');
  }
}

// 初始化主题
const savedTheme = localStorage.getItem('color-theme');
if (savedTheme) {
  // 优先使用本地存储的主题设置
  updateTheme(savedTheme === 'dark');
} else {
  // 无本地存储时,跟随系统偏好
  updateTheme(darkModeMediaQuery.matches);
}

// 手动切换主题按钮事件
themeToggleBtn.addEventListener('click', function() {
  const currentIsDark = document.documentElement.classList.contains('dark');
  const newTheme = currentIsDark ? 'light' : 'dark';
  
  updateTheme(!currentIsDark);
  localStorage.setItem('color-theme', newTheme);
});

// 监听系统配色偏好变化
darkModeMediaQuery.addEventListener('change', function(e) {
  // 仅当用户未手动设置过主题时,跟随系统变化
  if (!localStorage.getItem('color-theme')) {
    updateTheme(e.matches);
  }
});

配套按钮代码

<button id="theme-toggle" type="button" class="p-2 rounded-full hover:bg-gray-200 dark:hover:bg-gray-700 transition-colors">
  <svg id="moon" class="hidden h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M20.354 15.354A9 9 0 018.646 3.646 9.003 9.003 0 0012 21a9.003 9.003 0 008.354-5.646z"></path>
  </svg>
  <svg id="sun" class="hidden h-5 w-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
    <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 3v1m0 16v1m9-9h-1M4 12H3m15.364 6.364l-.707-.707M6.343 6.343l-.707-.707m12.728 0l-.707.707M6.343 17.657l-.707.707M16 12a4 4 0 11-8 0 4 4 0 018 0z"></path>
  </svg>
</button>

关键修改说明

  • 抽离updateTheme函数,统一处理主题类切换和图标显示逻辑,避免代码冗余
  • 初始化阶段修复:无本地存储时,根据系统偏好正确设置dark类和对应图标
  • 添加prefers-color-scheme媒体查询监听,用户未手动设置主题时,自动跟随系统主题变化
  • 简化手动切换逻辑,直接通过当前主题状态判断新主题,代码更简洁

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 10:25:20