现在很多网页和App都配备了“暗黑模式”,为了让人们在夜晚访问时不那么刺眼。
我非常喜欢“暗黑模式”。事实上即使不在晚上我也用的是“暗黑模式”。
🔬研究 #
最近在大佬的博客源码的首页 index.html
下看到这个👇
<script>
(function () {
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
const setting = localStorage.getItem('vueuse-color-scheme') || 'auto'
if (setting === 'dark' || (prefersDark && setting !== 'light'))
document.documentElement.classList.toggle('dark', true)
})()
</script>
这是一个判断网页浏览器是否为“暗黑模式”的代码
逻辑是
window.matchMedia('(prefers-color-scheme: dark)').matches
判断浏览器是否为暗黑模式,返回Ture/False给到变量prefersDark
localStorage.getItem('vueuse-color-scheme') || 'auto'
获取浏览器本地存储的主题模式记录,返回给变量setting
- 接下来判断
- 如果【setting】是黑的,那么网页也黑。
- 如果浏览器黑且【setting】不是白,那么网页也黑。
判断完毕后,只是在 <html>
这个标签多加上一个 “dark”
的类名
<html class='dark'>
//....
</html>
后续再说如何根据这个类名来变黑。
知识点一:立即执行函数 #
什么是立即执行函数?JS立即执行函数模式是一种语法,可以让你的函数在定义后立即被执行,这种模式本质上就是函数表达式(命名的或者匿名的),在创建后立即执行。
(funcion(){
//...
})()
知识点二:matchMedia()
#
matchMedia()
方法的值可以是任何一个 CSS @media 规则 的特性, 如 min-height, min-width, orientation 等。
用以下代码可以查询用户的浏览器是否“暗黑模式” 如是,prefersDark 为 True。
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
可以在浏览器的控制台输入以下这句👇
window.matchMedia('(prefers-color-scheme: dark)')
知识点三:localStorage
#
localStorage.setItem(键,值) 就是把(键值对)长期保存在浏览器存储里。
localStorage.getItem(键) 就是把值取出来。
//存👇
localStorage.setItem('保存的钥匙','保存的内容')
//取👇
let key = localStorage.getItem('保存的钥匙')
console.log(key)// 保存的内容
在浏览器按下F12,可以在控制台上的 “应用程序” -> “本地存储” 上看到。
知识点四:document #
document.documentElement #
简单理解用它来获取 根元素
- <html>
标签
classList #
classList 属性返回元素的类名。用于添加,移除及切换 CSS 类。
add(class1,class2)
添加类名contains(class)
判断是否存在item(index)
返回索引值对应类名remove(class1,class2)
移除类名toggle(class,true/false)
切换类名- 参数1:类名,如果存在则移除且返回false,不存在则添加返回true。
- 参数2:可选,用于设置元素是否强制添加或移除类,不管该类名是否存在。
所以我们使用 👇 就可以在<html>
上动态添加 dark
类名了。
document.documentElement.classList.toggle('dark',true)
🌗 配置 CSS #
前面已经介绍了,如何判断浏览器是否处于“暗黑模式”,并且判断完后在根元素 <html>
挂上 dark
这个类名
接下来就说说如何根据类目来切换颜色。
body{
background-color: white;
}
html.dark body{
background-color: black;
}
.text{
color: black;
}
html.dark .text{
color:white;
}
- 定义【字】默认颜色为黑色,【背景】默认白色。
- 当在类名“dark”下的则为【字】白色,【背景】黑色。
👇 写一个测试用的 html 文件
<!DOCTYPE html>
<html>
<head>
<title>测试暗黑模式</title>
<script>
(function () {
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
const setting = localStorage.getItem('vueuse-color-scheme') || 'auto'
if (setting === 'dark' || (prefersDark && setting !== 'light'))
document.documentElement.classList.toggle('dark')
})()
function toggleDark(){
document.documentElement.classList.toggle('dark')
}
</script>
<style>
body{
background-color: white;
}
html.dark body{
background-color: black;
}
.text{
color: black;
}
html.dark .text{
color:white;
}
</style>
</head>
<body>
<div class="text">暗黑模式</div>
<button onclick="toggleDark()">切换</button>
</body>
</html>
到这一步,其实已经可以切换暗黑模式了。
🎉优化 #
css变量 #
像上面,如果每一个class 都要设置一个“光亮”的值,一个“暗黑”的值,那就太麻烦了。
我们可以先利用CSS变量,预先设置一些变量名,这些变量名要符合所用的属性,比如叫【text】的就是字,【bg】就是背景,然后再给这个变量在光亮模式下选一个颜色,在暗黑模式下选一个颜色。👇
/* 这里负责定义颜色
在其他地方在这里调颜色用 */
html {
--text-color: #333; /* 黑字 */
--bg-color: #fff; /* 白底 */
}
html.dark {
--text-color: #fff; /* 白字 */
--bg-color: #333; /* 黑底 */
}
选完以后,我们再把这些变量运用到实际上的配色中。👇
/* 在其他地方在这里调颜色用👇 */
body {
background-color: var(--bg-color);
}
.text {
color: var(--text-color);
}
当你需要设置的类目非常多时,这个方法就很方便了。
dark & auto & light #
我们可以设置三个按钮让用于来选择当前是黑、白、或是自动。
【设置三个按钮控制也不错,以下这步不是必须的】
像本博客一样一个按钮实现三种情况👇
当用户点击按钮时,根据不同情况改变存储在本地的主题信息。
- 浏览器黑,页白,点 -> 存 auto
- 浏览器白,页黑,点 -> 存 auto
- 浏览器黑,页黑,点 -> 存 light
- 浏览器白,页白,点 -> 存 dark
function toggleDark() {
//判断浏览器是否为黑
const prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches
//判断页面是否为黑
const pageDark = document.documentElement.classList.contains('dark')
//改变页面的颜色,并且保存到浏览器中。
document.documentElement.classList.toggle('dark')
if (prefersDark != pageDark) {
localStorage.setItem('prefers-color-scheme', 'auto')
} else {
let color = pageDark ? 'light' : 'dark'
localStorage.setItem('prefers-color-scheme', color)
}
}
监听浏览器颜色的变换 #
通常浏览器在变色的时候,网页是不会跟着变化的,除非你按刷新按钮,或者去监听👇
window.addEventListener('perfers-color-scheme-change', () => {
// do something
})
更好的办法👇 #
在 MediaQueryList 上添加一个带有回调的事件监听器由 Window.matchMedia() 返回:
const darkModePreference = window.matchMedia("(prefers-color-scheme: dark)");
darkModePreference.addEventListener("change", () => localStorage.getItem('prefers-color-scheme')=='auto' && activateDarkMode());
function activateDarkMode() {
document.documentElement.classList.toggle('dark')
}
监听浏览器的黑白变换,当存储的值是auto才会随着变化!
VueUse 插件 #
【以下这步也不是必须的,只是用插件更加方便】
useDark & useToggle #
import { useDark, useToggle } from '@vueuse/core'
const isDark = useDark()
const toggleDark = useToggle(isDark) //这个会
useDark()
判断当前网页(html标签上有没有dark类)useToggle()
切换html.dark
usePreferredDark #
import { usePreferredDark } from '@vueuse/core'
const isDark = usePreferredDark()
//
usePreferredDark()
判断当前浏览器是否黑色
在Vue项目中,安装VueUse这个插件然后配置好以上。就可以更加方便的调用我们的暗黑模式啦!