這里給大家分享我在網上總結出來的一些知識,希望對大家有所幫助
核心
- 使用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
下一篇:返回列表

