这个月 LinusTechTips 怼出了一期视频专门讲了讲 "DARK Mod" ,确实,夜间刷刷刷的时候还是黑底白字看起来更顺眼一点。这回,我来给博客加上夜间模式,加入 Deep♂Dark♂Family (咳咳咳皮了)。

HeadPic

看到右下角的“暗”按钮了吗?点击它,开始你的黑暗之旅吧!

思路

本质上讲,Dark Mode 就是在指定时间段内修改页面配色、图片亮度等,既然是动态修改的,就免不了要用到 JavaScript 了。

样式有三种书写形式,分别为外联 ( 额外的 .css 文件,在 HTML 中使用 <link rel="stylesheet" href="..."> 建立连接 ) 、内联 ( 使用 <style>...</style> 将样式写在 HTML 中 ) 和内嵌 ( 在元素上使用 style="..." ) 。使用 JS 修改样式,就有以下三种方式进行操作:

1.引入一个新的外联 CSS 文件,以覆盖原有样式 ( 不影响原有样式文件、方便维护 ) 。
2.在原有 CSS 上追加样式,以 class 名区分 ( 方便 JS 操作,实现优雅、方便维护 ) 。
3.直接修改元素的 style 属性,即内嵌样式 ( 不推荐 ) 。

在这里博主选用第二种方法。

实现

使用 JS 控制元素 class

JSElement.classListadd()remove() 方法,正好满足我们的需求,且支持绝大多数浏览器支持。但先别急着写,还有一个细节:夜间模式这个状态应被保存下来一直生效,或持续到本次会话 Session 结束,cookie 可以满足我们的要求。

所以事情就很明朗了,编写代码:

function switchDarkMode(){
    var night = document.cookie.replace(/(?:(?:^|.*;\s*)dark\s*\=\s*([^;]*).*$)|^.*$/, "$1") || '0';
    if (night == '0'){
        document.body.classList.add('dark');
        document.cookie = "dark=1;path=/";
        console.log('Dark mode on');
    }else{
        document.body.classList.remove('dark');
        document.cookie = "dark=0;path=/";
        console.log('Dark mode off');
    }
}

即可实现夜间模式的 切换状态保存

在指定时间段内修改

思路很简单,页面加载后判断时间,在指定范围内修改元素 class

(function(){
    if(document.cookie.replace(/(?:(?:^|.*;\s*)dark\s*\=\s*([^;]*).*$)|^.*$/, "$1") === ''){
        if(new Date().getHours() > 22 || new Date().getHours() < 6){
            document.body.classList.add('dark');
            document.cookie = "dark=1;path=/";
            console.log('Dark mode on');
        }else{
            document.body.classList.remove('dark');
            document.cookie = "dark=0;path=/";
            console.log('Dark mode off');
        }
    }else{
        var dark = document.cookie.replace(/(?:(?:^|.*;\s*)dark\s*\=\s*([^;]*).*$)|^.*$/, "$1") || '0';
        if(dark == '0'){
            document.body.classList.remove('dark');
        }else if(dark == '1'){
            document.body.classList.add('dark');
        }
    }
})();

具体的样式内容

在上面的代码中,我们控制了 <body> 元素的 class,这是所有页面元素的祖先元素。启用夜间模式时,<body>class 值含有 dark ( 即 <body class="dark"> ) 。因此在编写夜间模式的样式时,在样式选择器前加 body.night 即可,可酌情使用 !important

图片亮度

使用 CSS 滤镜中的 brightness() 滤镜 ( 仅支持现代浏览器 ) 可以实现:

body.night img {
    filter: brightness(50%);
}

后端处理

因为是在本地通过 JS 操控样式,所以在 JS 加载前后样式不一样,会导致页面闪烁 然后闪瞎。可在博客主题中加上判断,当检测到 cookie含有相关字段后可直接输出 <body class="dark"> ,如:

<body class="<?php if($_COOKIE['dark']=='1'){echo'dark';} ?>">

加个按钮

这个就随网站样式而定啦,只要在元素上加上 onclick="switchDarkMode()" 就行了。

动态修改按钮内容

你可能注意到了,本站右下角的 Dark Mode 切换按钮上的字是会变的,即在 Dark Mode 开启时显示“亮”,关闭时显示“暗”,其实用 innerHTML 就可以更改啦。这样的话就需要在按钮元素上加个 id="..." ,然后在 JS 上加行代码。

这是本站使用的代码:

按钮:

<li id="darkmode" onclick="switchDarkMode()"><?php if($_COOKIE['dark']=='1'){echo"亮";}else{echo"暗";} ?></li>

JavaScript

function switchDarkMode(){
    var night = document.cookie.replace(/(?:(?:^|.*;\s*)dark\s*\=\s*([^;]*).*$)|^.*$/, "$1") || '0';
    if (night == '0'){
        document.body.classList.add('dark');
        document.cookie = "dark=1;path=/";
        console.log('Dark mode on');
        document.getElementById("darkmode").innerHTML="亮";
    }else{
        document.body.classList.remove('dark');
        document.cookie = "dark=0;path=/";
        console.log('Dark mode off');
        document.getElementById("darkmode").innerHTML="暗";
    }
}
(function(){
    if(document.cookie.replace(/(?:(?:^|.*;\s*)dark\s*\=\s*([^;]*).*$)|^.*$/, "$1") === ''){
        if(new Date().getHours() > 22 || new Date().getHours() < 6){
            document.body.classList.add('dark');
            document.cookie = "dark=1;path=/";
            console.log('Dark mode on');
            document.getElementById("darkmode").innerHTML="亮";
        }else{
            document.body.classList.remove('dark');
            document.cookie = "dark=0;path=/";
            console.log('Dark mode off');
            document.getElementById("darkmode").innerHTML="暗";
        }
    }else{
        var dark = document.cookie.replace(/(?:(?:^|.*;\s*)dark\s*\=\s*([^;]*).*$)|^.*$/, "$1") || '0';
        if(dark == '0'){
            document.body.classList.remove('dark');
        }else if(dark == '1'){
            document.body.classList.add('dark');
        }
    }
})();

鸣谢

本文参考由 journey.ad 创作的文章 给博客添加夜间模式 - 猫与向日葵 ,原文使用 知识共享署名 4.0 国际 (CC BY 4.0) 许可协议进行许可,本文的部分内容使用了该文章部分内容且进行了部分修改。

文章目录