js如何实现夜间模式切换 深色模式的5种实现方法分享!

js如何实现夜间模式切换 深色模式的5种实现方法分享!
最新回答
如一

2026-10-23 01:10:51

JS实现夜间模式切换:深色模式的5种实现方法

实现夜间模式(深色模式)的核心在于通过JS动态修改样式,以下是5种常见实现方法及其代码示例:

1. CSS类名切换

通过切换body或特定容器的class实现主题切换,是最简单直接的方法。

const body = document.body;const toggleButton = document.getElementById('toggle-button');toggleButton.addEventListener('click', () => { body.classList.toggle('dark-mode'); // 保存当前模式到localStorage localStorage.setItem('theme', body.classList.contains('dark-mode') ? 'dark' : 'light');});// 页面加载时检查localStorageif (localStorage.getItem('theme') === 'dark') { body.classList.add('dark-mode');}

CSS示例:

body { background-color: #fff; color: #000;}body.dark-mode { background-color: #121212; color: #e0e0e0;}

优点:

  • 实现简单,兼容性好
  • 无需复杂技术栈

缺点:

  • 需要维护两套CSS样式
  • 项目较大时维护成本增加

2. CSS变量(Custom Properties)

使用CSS变量定义颜色等样式,通过JS修改变量值实现主题切换。

// JS代码与类名切换类似,切换dark-mode类名即可const body = document.body;const toggleButton = document.getElementById('toggle-button');toggleButton.addEventListener('click', () => { body.classList.toggle('dark-mode'); localStorage.setItem('theme', body.classList.contains('dark-mode') ? 'dark' : 'light');});

CSS示例:

:root { --bg-color: #fff; --text-color: #000;}body { background-color: var(--bg-color); color: var(--text-color);}.dark-mode { --bg-color: #121212; --text-color: #e0e0e0;}

优点:

  • 方便统一管理样式
  • 易于维护和扩展
  • 支持动态修改

缺点:

  • 兼容性不如类名切换(IE不支持)
  • 旧浏览器需要polyfill

3. prefers-color-scheme媒体查询

监听用户系统主题设置自动切换,无需JS干预。

body { background-color: #fff; color: #000;}@media (prefers-color-scheme: dark) { body { background-color: #121212; color: #e0e0e0; }}

JS增强版(支持手动切换):

const body = document.body;const toggleButton = document.getElementById('toggle-button');// 检查系统偏好const systemPrefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;// 初始化主题if (localStorage.getItem('theme') === 'dark' || (localStorage.getItem('theme') === null && systemPrefersDark)) { body.classList.add('dark-mode');}// 切换按钮事件toggleButton.addEventListener('click', () => { body.classList.toggle('dark-mode'); localStorage.setItem('theme', body.classList.contains('dark-mode') ? 'dark' : 'light');});

优点:

  • 自动适应用户系统设置
  • 无需JS即可实现基本功能
  • 提升用户体验一致性

缺点:

  • 无法单独依赖(需结合其他方法实现手动切换)
  • 用户系统设置可能不符合其当前偏好

4. CSS Filters

使用filter属性反转颜色实现简单深色模式。

const toggleButton = document.getElementById('toggle-button');const body = document.body;toggleButton.addEventListener('click', () => { body.classList.toggle('dark-mode');});

CSS示例:

body { transition: filter 0.3s ease;}body.dark-mode { filter: invert(100%) hue-rotate(180deg);}

优点:

  • 实现简单,代码量少
  • 无需定义多套样式

缺点:

  • 效果不理想(可能影响图片和颜色准确性)
  • 性能开销较大(特别是动画时)
  • 不推荐用于生产环境

5. 动态加载CSS文件

通过切换不同CSS文件实现主题隔离。

const toggleButton = document.getElementById('toggle-button');const link = document.getElementById('theme-link');toggleButton.addEventListener('click', () => { const currentTheme = link.getAttribute('href'); const newTheme = currentTheme === 'light.css' ? 'dark.css' : 'light.css'; link.setAttribute('href', newTheme); localStorage.setItem('theme', newTheme.replace('.css', ''));});// 初始化主题if (localStorage.getItem('theme') === 'dark') { link.setAttribute('href', 'dark.css');} else { link.setAttribute('href', 'light.css');}

HTML示例:

<link id="theme-link" rel="stylesheet" href="light.css">

优点:

  • 主题样式完全隔离
  • 便于大型项目维护
  • 支持复杂主题配置

缺点:

  • 需要加载额外CSS文件
  • 切换时可能有闪烁
  • 性能影响较大(特别是CSS文件较大时)

深色模式设计原则

实现深色模式时需遵循以下原则:

  1. 可读性:

    避免纯黑色背景(#000),推荐使用深灰色(#121212)

    文本对比度至少4.5:1(WCAG标准)

    避免低对比度配色

  2. 品牌一致性:

    保持与亮色模式相同的品牌色调

    调整颜色时保持品牌识别度

    图标和图形元素需适配深色背景

  3. 视觉舒适度:

    避免高饱和度颜色

    使用柔和的过渡效果

    考虑环境光影响(夜间使用场景)

  4. 媒体内容处理:

    图片:提供深色模式优化版本或使用混合模式

    视频:考虑添加暗角效果或调整亮度

    图标:使用反色或专门设计的深色版本

性能优化建议

  1. CSS实现选择:

    小型项目:优先选择类名切换

    中型项目:CSS变量更易维护

    大型项目:考虑动态CSS加载

  2. 缓存策略:

    使用localStorage保存用户偏好

    设置适当的CSS缓存时间

    考虑Service Worker缓存主题资源

  3. 加载优化:

    预加载深色模式CSS

    使用媒体查询条件加载

    对主题图片进行懒加载

  4. 过渡效果:

    添加平滑的过渡动画

    避免主题切换时的闪烁

    使用CSS will-change提升性能

完整实现示例

结合多种方法的增强版实现:

<!DOCTYPE html><html><head> <meta charset="UTF-8"> <title>深色模式示例</title> <style> :root { --bg-color: #ffffff; --text-color: #000000; --primary-color: #4285f4; } body { background-color: var(--bg-color); color: var(--text-color); transition: background-color 0.3s, color 0.3s; margin: 0; padding: 20px; font-family: Arial, sans-serif; }