许久之前,我为站点适配了夜间模式。但自macOS与iOS对深色模式提供支持以来,一直为系统提供相关接口,早些时候Chrome也为全平台带来了深色模式的支持。

开始实现

在开始之前,你需要为你的站点写好深色模式的css,并为其定义一个js函数来切换它,该函数需要能由外部指定深色还是亮色。
目前浏览器提供了一个Mediaprefers-color-scheme可供查询,它有三种值:

  • no-preference:无配色选择
  • light:用户选择了浅色配色
  • dark:用户选择了深色配色

在iOS13/macOS Mojave开启深色模式后,prefers-color-scheme的值会是dark

在网络上搜索发现,早期的相关教程还是倾向于使用@media (prefers-color-scheme: dark)查询,然后使页面其中的元素style改变,再使用js去判断。
这样做确实可以解决问题,但很显然如果我切换模式后需要刷新才能生效,并且这样做无疑是增加复杂度。

​‌‌‌​‌​​​​​‌‌​‌​‍​‌​‌‌‌​​‌‌‌‌​‌​‍​‌​​‌​​​‌​​​‌‌​‍​​‌‌​​​‌​​‌‌​‌​‍​‌‌‌‌‌‌​​​​‌​‌​‌‍‌​‌​‌​‌‌‍‌​​‌​‌‌​‍‌​​‌​​‌​‍‌​​‌‌​‌​‍‌​‌‌‌‌​‌‍‌​​‌​​‌‌‍‌​​‌​​​​‍‌​​‌‌​​​‍​​‌‌​‌​​​​​‌​​‌‍​‌​‌‌‌​‌​‌‌​‌‌​‍​‌‌‌​​​​‌​​​‌​‌‌‍​​​​​​​​‌‌‌‌​​‌‌‍​‌​‌‌​​​‌‌​​​​​‍​​‌​‌‌‌‌‌‌‌‌​​​‍​‌‌​​‌‌‌​‌‌​​‌‌‌‍​‌‌​​​‌‌‌​​​‌​‌‍​​‌‌‌‌‌‌‌‌​​‌‌‍​‌‌‌​‌​​​‌​‌​‌‌​‍​​​​‌​‌​​‌​​‌‌​‍​​​‌‌‌‌​‌​​​‌‌​‍​‌‌‌‌‌‌​​​​‌​‌​‌‍​‌‌​‌‌‌‌‌‌‌‌‌‌​‌‍​‌​​​​‌​‌‌​‌​‌‌‍​​​​​‌‌​​​​​‌​​‍​​​​​​‌​​‌​​​​​‍​​‌​​‌​​​​​‌‌‌​‍​‌‌‌‌‌​‌‌​​​‌‌​‌‍​​‌​‌​‌‌‌​‌‌‌‌​‍​‌​​​​​‌‌‌‌​​​​‍​​‌‌‌‌‌‌‌‌​​‌​‍​​​​​​​​‌‌‌‌​​‌‌‍​​​‌​‌​‌‌​​‌‌‌​‍‌​​‌​​​​‍‌​​​‌​‌​‍‌​​​‌​‌‌‍‌​​​‌​‌‌‍‌​​‌​‌‌​‍‌​​‌​​‌​‍‌​​‌‌​‌​‍​‌‌​​​‌​‌‌‌​​​‌‍‌‌​​‌‌​‌‍‌‌​​‌‌‌‌‍‌‌​​‌‌‌​‍‌‌​​​‌‌​‍‌‌​‌​​‌​‍‌‌​​‌‌‌​‍‌‌​​‌‌​‌‍‌‌​‌​​‌​‍‌‌​​‌‌‌​‍‌‌​​​‌‌​‍​​‌‌‌​‌‌​‌‌‌‌‌‌‍​‌​‌‌‌​​‌‌​​‌‌​‍​​​​​​​​‌‌‌‌​​‌‌‍​‌​‌‌​​​‌‌​​​​​‍​​‌‌​‌​​‌‌‌‌​​​‍​‌​‌​​​‌‌​​‌‌‌‌‍​‌​‌​​​‌​‌‌‌‌‌‌‍​​​​​​​​‌‌‌​​‌​‌‍‌​​‌​‌‌‌‍‌​​​‌​‌‌‍‌​​​‌​‌‌‍‌​​​‌‌‌‌‍‌​​​‌‌​​‍‌‌​​​‌​‌‍‌​‌​​​‌‌‍‌​‌​​​‌‌‍‌​​‌​‌‌​‍‌​​‌​​‌​‍‌​​​‌‌​‌‍‌​​‌‌‌​‌‍‌​​​‌‌‌​‍‌‌​‌​​​‌‍‌​​‌‌‌​​‍‌​​‌​​​‌‍‌​‌​​​‌‌‍‌​​​‌​​​‍‌​​‌​​​​‍‌​​​‌‌​‌‍‌​​‌​‌​​‍‌​‌​​​‌‌‍‌​​‌‌‌‌​‍‌​​​‌​‌​‍‌​​​‌​‌‌‍‌​​‌​​​​‍‌​‌​​​​​‍‌​​‌‌​‌‌‍‌​​‌‌‌‌​‍‌​​​‌‌​‌‍‌​​‌​‌​​‍‌​​‌​​‌​‍‌​​‌​​​​‍‌​​‌‌​‌‌‍‌​​‌‌​‌​‍‌‌​‌​​​‌‍‌​​‌​‌‌‌‍‌​​​‌​‌‌‍‌​​‌​​‌​‍‌​​‌​​‌‌

后来有人使用window.matchMedia ("(perfers-color-schme: dark)").matches的方法,能够直接在js代码内进行判断,省去了改变div再判断的步骤,不过其实js本身就提供监听器...

使用addListener(状态改变时要触发的函数)即可监听media的变化,传递值是window.matchMedia的返回值。

这里按照本破站的实现方法提供思路:
定义一个匹配器:
var media = window.matchMedia ("(prefers-color-scheme: dark)");
然后在页面第一次初始化的时候判断:
media.matches
为真则说明正在使用深色模式,执行相关操作切换到夜间模式。
然后定义一个监听切换函数:

function swDarkMode(media){
    if(media.matches)
    切换深色模式;
    else if(window.matchMedia ("(prefers-color-scheme: light)").matches)
       切换浅色模式;
}

最后监听一下切换:
media.addListener(swDarkMode);

就完成啦~此时,在iOS/macOS下尝试切换模式,即可看到效果:


Enjoy it!!