切换效果
<!DOCTYPE html>
<html lang="en" data-theme="dark">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>切换光暗以及跟随系统</title>
<link rel="stylesheet" href="//at.alicdn.com/t/c/font_3996572_oqtn8obatf.css">
<style>
*{padding: 0;margin: 0;list-style: none;}
html[data-theme = "dark"]{
--bgColor1 : rgb(1, 22, 20);
--bgColor2 : rgb(59, 65, 3);
--text-color : #fff;
}
:root{
--bgColor1 : rgb(177, 249, 243);
--bgColor2 : rgb(237, 244, 177);
--text-color : #000;
}
html,body{
width: 100%;
height: 100%;
background: linear-gradient(to bottom,var(--bgColor1),var(--bgColor2));
padding: 30px;
box-sizing: border-box;
}
#box{
width: 100%;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
color: var(--text-color);
}
.control{
margin-top: 15px;
display: flex;
align-items: center;
}
.control i{
font-size: 35px;
font-weight: bold;
margin: 0px 10px;
}
.control i:nth-child(1){
color: orange;
}
.control i:nth-child(2){
color: rgb(22, 157, 167);
}
#checkipt{
display: none;
}
#iptlabel{
position: relative;
user-select: none;
display: inline-block;
width: 120px;
height: 40px;
background-color: #6b7c8c;
border-radius: 20px;
padding: 2px 5px;
transition: .3s;
box-shadow: inset 0 0 5px #fff;
--iptcolor : #a4d2df
}
#iptlabel::after{
content: '';
position: absolute;
width: 36px;
height: 36px;
border-radius: 50%;
background-color: var(--iptcolor);
transform: translateY(5%);
transition: .3s;
}
#iptlabel:hover{
--iptcolor : #fff
}
#checkipt:checked ~ #box label::after{
transform: translate(85px,5%);
}
.text{
margin-top: 30px;
font-size: 20px;
font-weight: bold;
color: var(--text-color);
}
/* Hide the default checkbox */
.control2{
margin-top: 20px;
}
.control2 .container input {
position: absolute;
opacity: 0;
cursor: pointer;
height: 0;
width: 0;
}
.control2 .container {
text-align: center;
display: block;
position: relative;
cursor: pointer;
font-size: 20px;
user-select: none;
}
/* Create a custom checkbox */
.control2 .checkmark {
position: relative;
top: 0;
left: 0;
height: 2.3em;
width: 2.3em;
background-color: #ccc;
border-radius: 50%;
transition: .4s;
}
.control2 .checkmark:hover {
box-shadow: inset 17px 17px 16px #b3b3b3,
inset -17px -17px 16px #ffffff;
}
/* When the checkbox is checked, add a blue background */
.control2 .container input:checked ~ .checkmark {
box-shadow: none;
background-color: limegreen;
transform: rotateX(360deg);
}
.control2 .container input:checked ~ .checkmark:hover {
box-shadow: 3px 3px 3px rgba(0,0,0,0.2);
}
/* Create the checkmark/indicator (hidden when not checked) */
.control2 .checkmark:after {
content: "";
position: absolute;
display: none;
}
/* Show the checkmark when checked */
.control2 .container input:checked ~ .checkmark:after {
display: block;
}
/* Style the checkmark/indicator */
.control2 .container .checkmark:after {
left: 0.96em;
top: 0.7em;
width: 0.25em;
height: 0.5em;
border: solid white;
border-width: 0 0.15em 0.15em 0;
box-shadow: 0.1em 0.1em 0em 0 rgba(0,0,0,0.3);
transform: rotate(45deg);
}
</style>
</head>
<body>
<input id="checkipt" type="checkbox">
<div id="box">
<h4>light</h4>
<div class="control">
<i class="iconfont icon-puguang"></i>
<label id="iptlabel" for="checkipt"></label>
<i class="iconfont icon-yueguang"></i>
</div>
<div class="control2">
<label class="container">
<input type="checkbox" checked>
<div class="checkmark"></div>
</label>
</div>
<p class="text">Theme 效果</p>
<p class="text">主题切换</p>
</div>
</body>
</html>
<script>
const THEME_KEY = 'THEME_KEY'
let ipt = document.getElementById('checkipt');
let box = document.getElementById('box')
txtTile = box.getElementsByTagName('h4')[0]
control2 = document.querySelector('.control2')
ipt2 = control2.querySelector('input')
systheme = false;
let curTheme = localStorage.getItem(THEME_KEY) || 'light'
const match = matchMedia('(prefers-color-scheme:dark)')
function init(){
checkStatus();
ipt.addEventListener('change',changeMode)
ipt2.addEventListener('change',changeMode)
changeMode()
}
init()
// 判断当前是跟随系统还是用户自定义
function checkStatus(){
systheme = ipt2.checked;
ipt.disabled = systheme
}
function changeMode(){
checkStatus();
ThemeInit();
controlChange();
}
function ThemeInit(){
// 跟随系统
if(systheme){
match.addEventListener('change',fllowOs)
curTheme = 'os';
localStorage.setItem(THEME_KEY,curTheme)
}
else{
match.removeEventListener('change',fllowOs)
ipt.checked ? curTheme = 'dark' : curTheme = 'light'
localStorage.setItem(THEME_KEY,curTheme)
}
}
function fllowOs(){
console.log('监听到了系统切换主题')
changeTheme()
}
function controlChange(){
changeText()
changeTheme()
}
function changeTheme(){
if(curTheme == 'os'){
document.documentElement.dataset.theme = match.matches ? 'dark' : 'light'
}
else{
document.documentElement.dataset.theme = curTheme
}
}
function changeText(){
if(curTheme == 'os'){
txtTile.innerText = '跟随系统'
return;
}
txtTile.innerText = curTheme
}
</script>
直接复制即可~