本文只阐述一下本博客的黑暗模式实现方式,或许对您有用。
继上一篇 github 的黑夜模式小猫咪动画源码 中已经提到了,我们是通过修改 html 根节点来控制整体的样式。
<html lang="en">
//改为:
<html lang="en" data-color-mode="light">
以及对应的 js 事件(包含了小猫咪的绑定事件):
// 切换按钮
function set_mode_toggle(e) {
let t = !0, mode = "dark";
"true" === e.getAttribute("aria-checked") && (t = !1 , mode = "light")
e.setAttribute("aria-checked", String(t))
change_mode(mode);
}
// 改变模式 并设置 cookie
function change_mode(e) {
const t = document.querySelector("html[data-color-mode]");
if (e === "dark") document.cookie = "night=1;path=/";
else document.cookie = "night=0;path=/"
t && t.setAttribute("data-color-mode", e)
}
// 获取当前模式
function get_user_scheme_mode() {
const e = document.querySelector("html[data-color-mode]");
if (!e)
return;
const t = e.getAttribute("data-color-mode");
return "auto" === t ? function() {
if (get_sys_scheme_mode("dark"))
return "dark";
if (get_sys_scheme_mode("light"))
return "light";
}() : t
}
// 获取系统模式 先判断 cookie 在获取系统的
function get_sys_scheme_mode(e) {
let night = document.cookie.replace(/(?:(?:^|.*;\s*)night\s*\=\s*([^;]*).*$)|^.*$/, "$1")
if (night){
if(night === '0'){
return false
}else if(night === '1'){
return true
}
}else
return window.matchMedia && window.matchMedia(`(prefers-color-scheme: ${e})`).matches
}
!async function() {
const e = document.querySelector(".js-promo-color-modes-toggle");
if (e && "auto" === function() {
const e = document.querySelector("html[data-color-mode]");
if (!e)
return;
return e.getAttribute("data-color-mode")
}()) {
"dark" === get_user_scheme_mode() && e.setAttribute("aria-checked", "true")
}
}()
!async function() {
document.querySelector(".js-color-mode-settings") && window.history.replaceState({}, document.title, document.URL.split("?")[0])
}()
// 添加点击事件
let toggle_btn = document.getElementsByClassName("js-promo-color-modes-toggle")
toggle_btn[0]? toggle_btn[0].addEventListener('click',function (e) {
set_mode_toggle(e.currentTarget)
},false):false
其中重要的是下面这个函数,当我们设置不同的模式的时候,顺便给 cookie 加上个值,比如我的是 night=1 表示黑暗模式。
function change_mode(e) {
const t = document.querySelector("html[data-color-mode]");
if (e === "dark") document.cookie = "night=1;path=/";
else document.cookie = "night=0;path=/"
t && t.setAttribute("data-color-mode", e)
}
有了上面这步,我们后台就可以通过cookie 来判断当前的模式,提前设置html节点,避免页面闪烁。
那么在 typecho 中,我们可以如下判断,还是以之前的 根节点为例:
<html lang="en" data-color-mode="<?php if($_COOKIE['night']=='1')echo 'dark';else echo 'light'; ?>">
这样就得到了黑暗模式根节点元素。
所以接下来就只需要修改对应的 css 即可。以下以scss为例:
[data-color-mode=dark] { // 黑暗模式下的样式
.j-dropdown{
background: var(--classD)!important;
}
.j-sidebar-xs{
.content{
.item{
border-bottom: 1px solid var(--classC);
}
}
}
xxxxx...
}
[data-color-mode=light] { // 白天模式下的样式
xxxxx...
}