這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助
核心
- 使用CSS變數, 準備兩套CSS顏色, 一套是在 light模式下的顏色,一套是在dark模式下的顏色
- dark模式下的 CSS 權重要比 light 模式下的權重高, 不然當我們給html添加自定義屬性
[data-theme='dark']
的時候, dark模式權重比light低,會一直不起效果 - 當我們點擊 dark 模式的時候, 給 html 設定自定義屬性
[data-theme='dark']
- 當我們點擊 light 模式的時候, 給 html 設定自定義屬性
[data-theme='light']
- 在 dark 模式下, 會匹配到
html[data-theme='dark']
選擇器下的樣式 - 在 light 模式下,由于我們沒有設定
html[data-theme='light']
的方案, 那么他就匹配:root(即html)下的樣式
兩套樣式代碼大概如下(列了一部分):
:root { --color-body-bg: #ffffff; --color-text: #000; --color-secondary-bg-for-transparent: rgba(209, 209, 214, 0.28); } html[data-theme='dark'] { --color-body-bg: #222222; --color-text: #ffffff; --color-primary-bg-for-transparent: rgba(255, 255, 255, 0.12); }然后我們點擊的時候,通過
let theme = 'light' // light / dark document.documentElement.setAttribute('data-theme', theme)
這樣就能實作簡單的更換膚色功能了
什么? 你以為這就完了?好戲剛開始
跟隨系統顏色
首先利用Window
的 'matchMedia()' 方法回傳一個新的 MediaQueryList
物件,表示指定的媒體查詢 (en-US)字串決議后的結果,
如運行媒體查詢(max-width: 600px)
并在<span>
;中顯示MediaQueryList
的matches
屬性值,如果視口的寬度小于或等于 600 像素,則輸出將為 true,而如果視窗的寬度大于此寬度,則將輸出 false,
<span ></span>
let mql = window.matchMedia('(max-width: 600px)'); document.querySelector(".mq-value").innerText = mql.matches; //此時小于或等于600像素時span 里面的結果為false
利用prefers-color-scheme
[CSS媒體特性] 用于檢測用戶是否有將系統的主題色設定為亮色或者暗色,
.day { background: #eee; color: black; } .night { background: #333; color: white; } @media (prefers-color-scheme: dark) { .day.dark-scheme { background: #333; color: white; } .night.dark-scheme { background: black; color: #ddd; } } @media (prefers-color-scheme: light) { .day.light-scheme { background: white; color: #555; } .night.light-scheme { background: #eee; color: black; } }
兩者相結合
把matchMedia()
和prefers-color-scheme
結合在一起, 我們就可以通過 js 去給系統顏色為dark或 light 的情況下更換對應的 html自定義屬性, 即[data-theme='dark']
或 [data-theme='light']
首先,我們先去獲取主題顏色, 我們還沒設定的時候,就默認是系統顏色, 設定了就把他存盤起來,下次直接獲取這個顏色
// 獲取主題變數 let appearance = ref<string>(localStorage.getItem('appearance') || 'auto') // 查詢當前系統主題顏色 const match = window.matchMedia("(prefers-color-scheme: dark)") // 如果主題變數為 auto, 則跟隨系統主題 if (appearance.value =https://www.cnblogs.com/smileZAZ/p/=='auto') { followSystem() } else { document.documentElement.setAttribute('data-theme', appearance.value) } function followSystem() { // 當前系統顏色是亮色還是暗色 , 設定對應的html[data-theme= 'dark' 或者'light'] const theme = match.matches ? 'dark' : 'light' document.documentElement.setAttribute('data-theme', theme) } // 監聽系統主題變化,電腦主題發生改變的時候就呼叫followSystem函式 match.addEventListener('change', followSystem)
封裝成一個hooks
暴露出一個 useThemeColor函式, 回傳一個物件, 物件里面回傳我們的主題變數
/ 獲取主題變數 let appearance = ref<string>(localStorage.getItem('appearance') || 'auto') // 查詢當前系統主題顏色 const match:MediaQueryList = window.matchMedia("(prefers-color-scheme: dark)") // 監聽系統主題變化 match.addEventListener('change', followSystem) function followSystem() { const theme = match.matches ? 'dark' : 'light' document.documentElement.setAttribute('data-theme', theme) } watchEffect(() => { // 如果主題變數為 auto, 則跟隨系統主題 if (appearance.value =https://www.cnblogs.com/smileZAZ/p/=='auto') { followSystem() } else { document.documentElement.setAttribute('data-theme', appearance.value) } }) export default function useThemeColor() { return { appearance, } }
使用hooks
匯入我們export出來的函式
import useThemeColor from '../hooks/useThemeColor'
使用函式,注意, 這里回傳的 apprance 已經是一個回應式資料了
const { appearance } = useThemeColor()
使用 v-model 系結apprance,直接使用apprance , 當我們切換顏色的時候, 就會呼叫watchEffect里面的函式, 達到一鍵換膚效果
<div > <div > <div >外觀</div> </div> <div > <select v-model="appearance"> <option value="https://www.cnblogs.com/smileZAZ/p/auto">{{ "自動" }}</option> <option value="https://www.cnblogs.com/smileZAZ/p/light">?? {{ "淺色" }}</option> <option value="https://www.cnblogs.com/smileZAZ/p/dark">?? {{ "深色" }}</option> </select> </div> </div>
本文轉載于:
https://juejin.cn/post/7237020208648634429
如果對您有所幫助,歡迎您點個關注,我會定時更新技術檔案,大家一起討論學習,一起進步,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/553879.html
標籤:HTML5
上一篇:HTML5
下一篇:返回列表