css - 仅在选中/取消选中复选框时转换
问题描述
我正在学习如何制作一个网站,并决定为它制作一个暗模式复选框。我设置了一个过渡:0.5s ease-in-out 让它看起来不错,但问题是每次我换页时都会发生过渡,这会伤害眼睛。我怎样才能使转换仅在我选中或取消选中复选框时发生。
const darkBtn = document.querySelector('.fas');
const bodyEl = document.querySelector('body');
const darkMode = () => {
bodyEl.classList.toggle('dark')
}
darkBtn.addEventListener('click', () => {
// Get the value of the "dark" item from the local storage on every click
setDarkMode = localStorage.getItem('dark');
if(setDarkMode !== "on") {
darkMode();
// Set the value of the item to "on" when dark mode is on
setDarkMode = localStorage.setItem('dark', 'on');
} else {
darkMode();
// Set the value of the item to "null" when dark mode if off
setDarkMode = localStorage.setItem('dark', null);
}
});
// Get the value of the "dark" item from the local storage
let setDarkMode = localStorage.getItem('dark');
// Check dark mode is on or off on page reload
if(setDarkMode === 'on') {
darkMode();
}
:root {
--body-color: #fff;
--heading-color: #1e202a;
--text-color: #1e202a;
}
* {
box-sizing: border-box;
}
html {
margin: 0;
padding: 0;
width: 100%;
height: 100vh;
}
body {
margin: 0;
padding: 0;
width: 100%;
height: 100vh;
font-family: Poppins;
font-weight: 400;
/* background: url(background-img.jpg);
background-repeat: no-repeat;
background-attachment: fixed;
background-position: center;
background-size: cover; */
background-color: var(--body-color);
transition: 0.5s ease-in-out;
}
nav {
padding: 8px;
}
.logo {
float: left;
padding: 8px;
margin-left: 16px;
margin-top: 8px;
}
.logo a {
color: #000;
text-transform: uppercase;
font-weight: 700;
font-size: 18px;
letter-spacing: 0px;
text-decoration: none;
color: var(--text-color);
}
nav ul {
float: right;
}
nav ul li {
display: inline-block;
float: left;
}
nav ul li:not(:first-child) {
margin-left: 48px;
}
nav ul li:last-child {
margin-right: 24px;
}
nav ul li a {
display: inline-block;
outline: none;
color: var(--text-color);
text-transform: uppercase;
text-decoration: none;
font-size: 14px;
letter-spacing: 1.2px;
font-weight: 600;
}
@media screen and (max-width: 864px) {
.logo {
padding: 0;
}
.nav-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: -1;
background: var(--body-color);
opacity: 0;
transition: all 0.2s ease;
color: var(--text-color);
}
.nav-wrapper ul {
position: absolute;
top: 50%;
transform: translateY(-50%);
width: 100%;
}
.nav-wrapper ul li {
display: block;
float: none;
width: 100%;
text-align: right;
margin-bottom: 10px;
}
.nav-wrapper ul li:nth-child(1) a {
transition-delay: 0s;
}
.nav-wrapper ul li:nth-child(2) a {
transition-delay: 0.1s;
}
.nav-wrapper ul li:nth-child(3) a {
transition-delay: 0.2s;
}
.nav-wrapper ul li:nth-child(4) a {
transition-delay: 0.3s;
}
.nav-wrapper ul li:nth-child(5) a {
transition-delay: 0.4s;
}
.nav-wrapper ul li:nth-child(6) a {
transition-delay: 0.5s;
}
.nav-wrapper ul li:not(:first-child) {
margin-left: 0;
}
.nav-wrapper ul li a {
padding: 10px 24px;
opacity: 0;
color: var(--text-color);
font-size: 14px;
font-weight: 600;
letter-spacing: 1.2px;
transform: translateX(-20px);
transition: all 0.2s ease;
}
.nav-wrapper ul li i {
padding-right: 35px;
}
.nav-btn {
position: fixed;
right: 10px;
top: 10px;
display: block;
width: 48px;
height: 48px;
cursor: pointer;
z-index: 9999;
border-radius: 50%;
}
.nav-btn i {
display: block;
width: 20px;
height: 2px;
background: var(--text-color);
border-radius: 2px;
margin-left: 14px;
}
.nav-btn i:nth-child(1) {
margin-top: 16px;
}
.nav-btn i:nth-child(2) {
margin-top: 4px;
opacity: 1;
}
.nav-btn i:nth-child(3) {
margin-top: 4px;
}
}
#nav:checked+.nav-btn {
transform: rotate(45deg);
}
#nav:checked+.nav-btn i {
background: var(--text-color);
transition: transform 0.2s ease;
}
#nav:checked+.nav-btn i:nth-child(1) {
transform: translateY(6px) rotate(180deg);
}
#nav:checked+.nav-btn i:nth-child(2) {
opacity: 0;
}
#nav:checked+.nav-btn i:nth-child(3) {
transform: translateY(-6px) rotate(90deg);
}
#nav:checked~.nav-wrapper {
z-index: 9990;
opacity: 1;
}
#nav:checked~.nav-wrapper ul li a {
opacity: 1;
transform: translateX(0);
}
.hidden {
display: none;
}
.dark {
--body-color: #1f212e;
--heading-color: #8b97c6;
--text-color: #fff;
}
.fas {
cursor: pointer;
color: var(--heading-color);
transform: rotate(-25deg);
}
.text {
padding-top: 20%;
font-family: "Poppins", sans-serif;
font-size: 15px;
font-weight: 400;
margin-right: 25%;
margin-left: 25%;
line-height: 1.8;
letter-spacing: 0em;
color: var(--text-color);
}
p {
font-family: "Poppins", sans-serif;
font-size: 15px;
font-weight: 400;
margin-right: 25%;
margin-left: 25%;
line-height: 1.8;
letter-spacing: 0em;
color: var(--text-color);
}
h1 {
font-family: "Futura-pt", sans-serif;
text-align: center;
font-size: 40px;
text-decoration: none;
margin-bottom: 20px;
margin-top: 100px;
color: var(--text-color);
/* color: var(--heading-color); */
}
a {
color: var(--text-color);
text-decoration: inherit;
font-family: "Futura-pt", sans-serif;
font-weight: 600;
line-height: 1.3;
letter-spacing: 0em;
}
iframe {
margin-left: 30%;
margin-top: 3%;
}
table {
margin-left: 25%;
font-family: "Futura-pt", sans-serif;
}
th {
padding: 1.4em;
color: var(--text-color);
}
td {
color: var(--text-color);
}
.lol {
text-align: center;
}
.skins {
margin-left: auto;
margin-right: auto;
}
caption {
margin-left: auto;
margin-right: auto;
margin-top: 2%;
font-family: "Futura-pt", sans-serif;
font-weight: 600;
color: var(--text-color);
}
.classes {
margin-left: auto;
margin-right: auto;
text-align: center;
}
.hobbit {
font-family: "Poppins", sans-serif;
font-size: 15px;
font-weight: 400;
margin-left: 290px;
line-height: 1.8;
letter-spacing: 0em;
color: var(--text-color);
}
.homelinks {
margin-left: 45%;
line-height: 1.8;
}
.box {
position: relative;
float: left;
width: 25%;
margin-left: -5%;
}
.box2 {
position: relative;
float: right;
width: 25%;
margin-right: 30%;
}
.undervids {
padding-top: 360px;
}
.sidemoon {
top: 10px;
right: 10px;
position: absolute;
display: none;
}
figcaption {
font-family: "Poppins", sans-serif;
}
.imgContainer {
float: left;
margin-left: 50px;
color: var(--text-color);
}
.imgContainer2 {
float: left;
margin-left: 20px;
color: var(--text-color);
}
figure {
text-align: center;
}
.lofivideos {
text-align: center;
padding-bottom: 20px;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Home</title>
<link rel="stylesheet" href="master.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css">
</head>
<body>
<div class="container">
<nav>
<input type="checkbox" id="nav" class="hidden">
<label for="nav" class="nav-btn">
<i></i>
<i></i>
<i></i>
</label>
<div class="logo">
<a href="index.html">SITE</a>
</div>
<div class="nav-wrapper">
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="Lofi.html">Lofi</a></li>
<li><a href="League_Of_Legends.html">LoL</a></li>
<!-- <li><a href="The_Hobbit.html">The Hobbit</a></li> -->
<li><a href="Tower_Of_God.html">ToG</a></li>
<li><a href="card.html">Contact</a></li>
<li><i class="fas fa-moon fa-2x"></i></li>
</ul>
</div>
</nav>
</div>
<div class="text">Lorem ipsum dolor sit amet consectetur adipisicing elit. Maxime vitae fugiat, velit, numquam totam vel sequi tempora, rerum nam earum repudiandae omnis consequuntur incidunt! Quam maxime quibusdam neque corporis tempore? Lorem ipsum dolor sit amet consectetur adipisicing elit. Impedit fugiat labore accusantium commodi tempore eaque veniam excepturi nulla dicta magni, aut saepe facilis cum consequuntur est inventore itaque laudantium corrupti.</div>
<script src="main.js"></script>
</body>
</html>
解决方案
不确定大量 CSS 正在尝试什么,因此对于这个答案,我将其作为问题的一部分删除。我决定切换一个数据属性值并通过它来选择,而不是切换一个类。我们可以有“lightblue”、“dark”、“light”等。
我使用了一个假的本地存储 - 但你可以再次在你的代码中解决这个问题(它在 StackOverflow 上不起作用,因此我为什么这样做不同)
现在回到您的问题:只需在页面加载之前/页面加载时设置数据属性中的值(在本例中为正文)。它最初应该很棒(它只是 CSS),但是当你切换它时会做任何事情。
为了清楚起见,我添加了与过渡相关的 CSS。
const darkBtn = document.querySelector('.fas');
function fakeLocalGet(itemName) {
const iholdstuff = document.querySelector('#i-hold-stuff');
return iholdstuff.dataset[itemName];
}
function fakeLocalSet(itemName, itemValue) {
const iholdstuff = document.querySelector('#i-hold-stuff');
iholdstuff.dataset[itemName] = itemValue;
}
var toggleState = function(elem, one, two) {
var elem = document.querySelector(elem);
elem.setAttribute('data-state', elem.getAttribute('data-state') === one ? two : one);
};
darkBtn.addEventListener('click', () => {
let isDarkMode = (fakeLocalGet('dark') === "on");
// console.log(isDarkMode);
if (isDarkMode) {
toggleState('body', 'dark', 'light');
fakeLocalSet('dark', 'on');
} else {
toggleState('body', 'light', 'dark');
fakeLocalSet('dark', 'off');
}
});
// initially set to light (dark off)
fakeLocalSet('dark', "off");
//toggleState('body', 'dark', 'light');
let setDarkMode = fakeLocalGet('dark');
// Check dark mode is on or off on page reload
/*
if (setDarkMode === 'on') {
darkMode();
}
*/
#i-hold-stuff {
display: none;
}
body[data-state=dark],
body[data-state=initial] {
background-color: #888888;
}
body[data-state=dark] {
transition: 0.75s ease-in-out;
}
body[data-state=light] {
background-color: #DDDDDD;
transition: 0.75s ease-in-out;
}
.showme {
border: solid #00ff00 1px;
color: #FF0000:
}
.hidden {
display: none;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.14.0/css/all.min.css" />
<body data-state="initial">
<div id="i-hold-stuff"></div>
<div class="container">
<nav>
<input type="checkbox" id="nav" class="hidden" />
<label for="nav" class="nav-btn">
<i></i>
<i></i>
<i></i>
</label>
<div class="logo">
<a href="index.html">SITE</a>
</div>
<div class="nav-wrapper">
<ul>
<li><a href="index.html">Home</a></li>
<li><a href="Lofi.html">Lofi</a></li>
<li><a href="League_Of_Legends.html">LoL</a></li>
<li><a href="Tower_Of_God.html">ToG</a></li>
<li><a href="card.html">Contact</a></li>
<li><i class="fas fa-moon fa-2x"></i></li>
</ul>
</div>
</nav>
</div>
<div class="text">Lorem ipsum dolor sit amet consectetur adipisicing elit. Maxime vitae fugiat, velit, numquam totam vel sequi tempora, rerum nam earum repudiandae omnis consequuntur incidunt! Quam maxime quibusdam neque corporis tempore? Lorem ipsum dolor sit amet consectetur
adipisicing elit. Impedit fugiat labore accusantium commodi tempore eaque veniam excepturi nulla dicta magni, aut saepe facilis cum consequuntur est inventore itaque laudantium corrupti.</div>
</body>
推荐阅读
- javascript - 如何将 defaultOption 添加到 AsyncSelect?
- ios - iOS 应用中 VoiceOver 在什么情况下会自动切换语言
- bash - 无法将 shopt globstar 输出保存到变量
- sql - 在 SQL Server 2008 中将条件变量转换为日期
- model-view-controller - 如何使用 Stripe API 在 .net core 2.0 中为客户订阅计划后获取 Charge ID
- c++ - 在结构的联合成员中使用 std::string 时无法引用默认构造函数
- javascript - Vue页面在本地读取数据后初始渲染失败
- angular - 这个语法在订阅中的含义是什么?
- javascript - 为什么 Animated.View 中的 ScrollView 不起作用?
- azure - Azure redis 缓存辅助数据库。无法访问