网页明暗模式切换的原生代码
实现网页明暗模式的切换有多种方式,各有优缺点,可有个人喜好选择使用。本文记录通过 html、css 和 javascript 三种语言实现切换功能的基本思路和代码。
基本思路
- 定义明暗两种模式:分别为 light 和 dark;其中 dark 表示暗模式,并且作为默认模式。
- 在
<html>
元素内添加自定义属性data-theme
,当data-theme = dark
时,页面渲染为暗模式;当data-theme = light
时,渲染为明模式。 - 在 body 体内添加切换点,点击后触发切换。
- 在 css 的根元素
:root
里分别定义两种模式的属性。 - 在 javascript 中,添加切换点的监听和动作,用于改变
data-theme
的值。
实现
HTML
1<!DOCTYPE html>
2<html data-theme="dark">
3 <head>
4 ...
5 </head>
6 <body>
7 ...
8 <div id="modeToggle">Mode Toggle</div>
9 ...
10 </body>
11</html>
CSS
1:root[data-theme="light"] {
2 --bg-base: white;
3 --ft-base: black;
4}
5
6:root[data-theme="dark"] {
7 --bg-base: black;
8 --ft-base: white;
9}
10
11body {
12 background-color: var(--bg-base);
13 color: var(--ft-base);
14}
JAVASCRIPT
1const modeToggle = document.getElementById("modeToggle");
2modeToggle.addEventListener("click",()=>{
3 const currentMode = document.documentElement.getAttribute("data-theme");
4 const targetMode = currentMode === "light" ? "dark" : "light";
5 document.documentElement.setAttribute("data-theme",targetMode);
6});
优化
通过上述实践,实现了页面明暗模式的切换,但是只适用于单页面网站。当页面跳转时,页面会重新渲染,切换后的模式不会带入到新的网页中;使用 Web API 接口对象 Window.sessionStorage 对 javascript 文件进行优化。
1if (sessionStorage.getItem('mode')) {
2 document.documentElement.setAttribute("data-theme",sessionStorage.getItem('mode'));
3}
4
5const modeToggle = document.getElementById("modeToggle");
6modeToggle.addEventListener("click",()=>{
7 const currentMode = document.documentElement.getAttribute("data-theme");
8 const targetMode = currentMode === "light" ? "dark" : "light";
9 document.documentElement.setAttribute("data-theme",targetMode);
10 sessionStorage.setItem("mode",targetMode);
11});
进一步优化
优化后,切换后的明暗模式被带入到新的页面,但是还存在一个问题:每次页面跳转时,会出现一次跳闪。这是因为页面刷新时,先渲染默认的明暗模式,然后再改变为需要的明暗模式。
解决的方法是将 javascript 文件中,判断明暗模式的语句,转移到 <head>
元素里。这样就可以在渲染页面之前就修改参数,直接渲染为需要的明暗模式。
HTML
1<!DOCTYPE html>
2<html data-theme="dark">
3 <head>
4 ...
5 <script>
6 if (sessionStorage.getItem('mode')) {
7 document.documentElement.setAttribute("data-theme",sessionStorage.getItem('mode'));
8 }
9 </script>
10 ...
11 </head>
12 <body>
13 ...
14 <div id="modeToggle">Mode Toggle</div>
15 ...
16 </body>
17</html>
JAVASCRIPT
1const modeToggle = document.getElementById("modeToggle");
2modeToggle.addEventListener("click",()=>{
3 const currentMode = document.documentElement.getAttribute("data-theme");
4 const targetMode = currentMode === "light" ? "dark" : "light";
5 document.documentElement.setAttribute("data-theme",targetMode);
6 sessionStorage.setItem("mode",targetMode);
7});