From cfccd511562518218ef63a807574c8d8e31a4580 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=91=98=E5=B0=8F=E5=A2=A8?= <2291200076@qq.com> Date: Sun, 22 May 2022 00:37:59 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=B7=B1=E8=89=B2=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F=EF=BC=9B=E4=BB=BB=E5=8A=A1=E6=A0=8F=E6=A0=B7=E5=BC=8F?= =?UTF-8?q?=E5=BE=AE=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/css/index.css | 53 +++++++++++++++++++++++- src/assets/js/darkmode.js | 85 +++++++++++++++++++++++++++++++++++++++ src/assets/js/header.js | 14 ++++++- src/index.html | 3 ++ 4 files changed, 152 insertions(+), 3 deletions(-) create mode 100644 src/assets/js/darkmode.js diff --git a/src/assets/css/index.css b/src/assets/css/index.css index c71d331..28f476b 100644 --- a/src/assets/css/index.css +++ b/src/assets/css/index.css @@ -19,6 +19,50 @@ a:hover { place-items: center; } +/* 深色模式 */ +:root { + --color-mode: "light"; + --color-dark: #141414; + --color-dark-alpha: rgba(0, 0, 0, 0.1); + + --color-light: #efefef; + --color-light-alpha: rgba(255, 255, 255, 0.9); + + --background: #efefef; + --text-color: #141414; + --button-background: var(--color-dark); + --button-color: var(--color-light); + --border-color: var(--color-dark-alpha); +} + +@media (prefers-color-scheme: dark) { + :root { + --color-mode: "dark"; + } + + :root:not([data-user-color-scheme]) { + --background: var(--color-dark); + --text-color: var(--color-light); + --button-background: var(--color-light); + --button-color: var(--color-dark); + --border-color: var(--color-light-alpha); + } +} + +[data-user-color-scheme="dark"] { + --background: var(--color-dark); + --text-color: var(--color-light); + --button-background: var(--color-light-alpha); + --button-color: var(--color-dark); + --border-color: var(--color-light-alpha); +} + +body { + background: var(--background); + color: var(--text-color); + transition: background 500ms ease-in-out, color 200ms ease; +} + /* 导航栏 */ #header { width: 100%; @@ -26,15 +70,16 @@ a:hover { position: fixed; top: 0; left: 0; - /* background-color: blue; */ + background-color: var(--background); box-shadow: 0 0 5px #888; + overflow-y: hidden; + user-select: none; } #header-wapper { display: grid; height: 100%; margin: 0 6vw; - /* background-color: red; */ grid-template-columns: 300px 1fr 300px; } @@ -43,6 +88,10 @@ a:hover { margin: auto 0; } +.header-logo-links a { + margin-left: 12px; +} + /* 正文 */ #container { border: 1px solid #999; diff --git a/src/assets/js/darkmode.js b/src/assets/js/darkmode.js new file mode 100644 index 0000000..2bfbc83 --- /dev/null +++ b/src/assets/js/darkmode.js @@ -0,0 +1,85 @@ +// refer: https://codepen.io/xgqfrms/pen/qBbdbbJ?editors=1010 + +const STORAGE_KEY = 'user-color-scheme'; +const COLOR_MODE_KEY = '--color-mode'; + +const modeToggleButton = document.querySelector('.js-mode-toggle'); +const modeToggleText = document.querySelector('.js-mode-toggle-text'); + +/** + * Pass in a custom prop key and this function will return its + * computed value. + * A reduced version of this: https://andy-bell.design/wrote/get-css-custom-property-value-with-javascript/ + */ +const getCSSCustomProp = (propKey) => { + let response = getComputedStyle(document.documentElement).getPropertyValue(propKey); + + // Tidy up the string if there’s something to work with + if (response.length) { + response = response.replace(/\'|"/g, '').trim(); + } + + // Return the string response by default + return response; +}; + +/** + * Takes either a passed settings ('light'|'dark') or grabs that from localStorage. + * If it can’t find the setting in either, it tries to load the CSS color mode, + * controlled by the media query + */ +const applySetting = passedSetting => { + let currentSetting = passedSetting || localStorage.getItem(STORAGE_KEY); + + if(currentSetting) { + document.documentElement.setAttribute('data-user-color-scheme', currentSetting); + setButtonLabelAndStatus(currentSetting); + } + else { + setButtonLabelAndStatus(getCSSCustomProp(COLOR_MODE_KEY)); + } +} + +/** + * Get’s the current setting > reverses it > stores it + */ +const toggleSetting = () => { + let currentSetting = localStorage.getItem(STORAGE_KEY); + + switch(currentSetting) { + case null: + currentSetting = getCSSCustomProp(COLOR_MODE_KEY) === 'dark' ? 'light' : 'dark'; + break; + case 'light': + currentSetting = 'dark'; + break; + case 'dark': + currentSetting = 'light'; + break; + } + + + localStorage.setItem(STORAGE_KEY, currentSetting); + + return currentSetting; +} + +/** + * A shared method for setting the button text label and visually hidden status element + */ +const setButtonLabelAndStatus = currentSetting => { + modeToggleText.innerText = `${currentSetting === 'dark' ? 'Light' : 'Dark'}`; +// modeStatusElement.innerText = `Color mode is now "${currentSetting}"`; +} + +/** + * Clicking the button runs the apply setting method which grabs its parameter + * from the toggle setting method. + */ +modeToggleButton.addEventListener('click', evt => { + evt.preventDefault(); + + applySetting(toggleSetting()); +}); + +applySetting(); \ No newline at end of file diff --git a/src/assets/js/header.js b/src/assets/js/header.js index 8bc48eb..b7a7c9f 100644 --- a/src/assets/js/header.js +++ b/src/assets/js/header.js @@ -2,7 +2,6 @@ function drawNavbar() { function createElement(json) { if (!json || json.length === 0) return null - console.log(1) var fr = document.createDocumentFragment() // var elList = [] for (let i = 0; i < json.length; i++) { @@ -70,6 +69,19 @@ function drawNavbar() { }, "innerHTML": "B站" }, + { + "tagName": "a", + "attr": { + "class": "js-mode-toggle js-mode-toggle-text", + "style": `line-height: 60px; + background: var(--button-icon); + background-size: contain; + background-repeat: no-repeat; + background-position: center;`, + "href": "javascript:void(0)", + }, + "innerHTML": "Dark" + }, ] }, ] diff --git a/src/index.html b/src/index.html index 1be54b5..be660d0 100644 --- a/src/index.html +++ b/src/index.html @@ -165,6 +165,9 @@ + + +