[博客美化]給自己的個人博客加上夜間模式並實現時間段的自動判斷


前言

現在很多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*)night\s*\=\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*)night\s*\=\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*)night\s*\=\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>


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM