• [博客美化]给自己的个人博客加上夜间模式并实现时间段的自动判断


    前言

    现在很多app 都已经实现了夜间模式,这样可以在夜间的时候保护我们的眼睛呢?于是,就有了给自己博客添加夜间模式的想法,花不多说,开始吧。

    预览

    直接点击按钮 开启/关闭夜间模式

    实现思路

    本质上讲,“夜间模式”就是在指定时间段内修改页面配色、图片亮度等,因此我们把问题拆开为三部分进行分析:

    • 动态修改页面配色、图片亮度
    • 在指定时间段内修改
    • 具体的样式内容

    动态修改页面配色、图片亮度 既然提到了动态,就免不了要用到JavaScript了。
    我们知道样式有三种书写形式,分别为外联、内联和内嵌。使用JS修改样式,就要从这三个地方入手:

    • 引入一个新的外联CSS文件,以覆盖原有样式  /不影响原有样式文件、方便维护/
    • 不引入新的CSS,而是在原有CSS上追加样式,以class名区分  /方便JS操作,实现优雅、方便维护/
    • 在页面中插入style标签,在其中书写样式  /不增加HTTP连接数、方便维护/
    • 修改元素的style属性,即内嵌样式  /不推荐/

    第四种方法违反了“结构与表现分离的设计思想”,且内嵌样式优先级过高
    而且真正实现的话,需要对大量元素编写JS代码,执行效率低下,维护困难,因此一般不作考虑
    前三种方法都有其适用场景,在这里选择第二种

    以class来区分样式,实现了功能与表现的分离。对于JS代码来说,问题变成了如何操作元素的class,而不必关心样式的具体表现。

    使用JS控制元素class

    JS中Element.classListadd()remove()方法,正好满足我们的需求,且支持绝大多数浏览器(IE10以上支持)
    但先别急着写,还有一个细节:夜间模式这个状态应被保存下来一直生效,或持续到本次会话结束,cookie可以满足我们的要求
    所以事情就很明朗了,编写代码:

    function switchNightMode(){
        var night = document.cookie.replace(/(?:(?:^|.*;s*)nights*=s*([^;]*).*$)|^.*$/, "$1") || '0';
        if(night == '0'){
            document.body.classList.add('night');
            document.cookie = "night=1;path=/"
            console.log('夜间模式开启');
        }else{
            document.body.classList.remove('night');
            document.cookie = "night=0;path=/"
            console.log('夜间模式关闭');
        }
    }
    

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

    在指定时间段内修改

    思路很简单,页面加载后判断时间,在指定范围内修改元素class。这里有一个知识点立即调用函数

    (function(){
        if(document.cookie.replace(/(?:(?:^|.*;s*)nights*=s*([^;]*).*$)|^.*$/, "$1") === ''){
            if(new Date().getHours() > 22 || new Date().getHours() < 6){
                document.body.classList.add('night');
                document.cookie = "night=1;path=/";
                console.log('夜间模式开启');
            }else{
                document.body.classList.remove('night');
                document.cookie = "night=0;path=/";
                console.log('夜间模式关闭');
            }
        }else{
            var night = document.cookie.replace(/(?:(?:^|.*;s*)nights*=s*([^;]*).*$)|^.*$/, "$1") || '0';
            if(night == '0'){
                document.body.classList.remove('night');
            }else if(night == '1'){
                document.body.classList.add('night');
            }
        }
    })();
    

    具体的样式内容

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

    body.night{
        background-color: #263238;
        color: #aaa;
    }
    

    图片亮度

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

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

    后端处理

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

    <body class="<?php echo($_COOKIE['night'] == '1' || date("H") > 22 || date("H") < 6 ? 'night' : ''); ?>">
    

    关于夜间模式在博客园实现的简单说明

    只需要两步就可以了,说明如下:

    • 通过上面的代码有两个js代码块 ,可以通过引用的方式引入,也可以通过写在侧边栏(记得博客园侧边栏是支持js的,我没有试过,请自行测试。)
    • 和上面的例子一样,对应着自己写夜间的css样式。

    版权声明

    部分资源引用于网络。
    Element.classList - Web API | MDN
    给博客添加夜间模式
    Document.cookie - Web API 接口 | MDN
    filter - CSS | MDN

    	<style type="text/css">
    	
             input[type="button"] {
    color: #353535;
    text-shadow: 0 1px 0 #fff;
    background-color: #f2f2f2;
    border-color: #bfbfbf;
    display: inline-block;
    padding: 5px 12px;
    margin-bottom: 0;
    font-size: 13px;
    font-weight: 400;
    line-height: 1.53846154;
    text-align: center;
    white-space: nowrap;
    vertical-align: middle;
    cursor: pointer;
    -webkit-user-select: none;
    -moz-user-select: none;
    -ms-user-select: none;
    user-select: none;
    border: 1px solid transparent;
    border-radius: 4px;
    -webkit-transition: all .4s cubic-bezier(.175,.885,.32,1);
    -o-transition: all .4s cubic-bezier(.175,.885,.32,1);
    transition: all .4s cubic-bezier(.175,.885,.32,1);
    

    border-color: #bfbfbf;
    }

    	</style>
    
  • 相关阅读:
    BZOJ5302: [Haoi2018]奇怪的背包
    BZOJ5303: [Haoi2018]反色游戏
    UOJ#217. 【UNR #1】奇怪的线段树(广义线段树性质+上下界最小流)
    Codeforces 702F T-Shirts(平衡树+复杂度分析)
    满足决策单调性的 DP 的通用做法
    JZOJ 6754. 2020.07.18【NOI2020】模拟T3 (树链剖分+分治+闵科夫斯基和)
    JZOJ 6756. 2020.07.21【NOI2020】模拟T2 (搜索有用状态+背包dp)
    JZOJ 6757 2020.07.21【NOI2020】模拟T3 (至少容斥+OGF+NTT)
    线性规划转对偶问题
    GDOI 2020 赛前反思
  • 原文地址:https://www.cnblogs.com/yjlaugus/p/8485293.html
Copyright © 2020-2023  润新知