使用javascript和CSS变量的localStorage制作切换主题按钮,但面临许多问题



我不敢相信我无法使用我所知道的所有资源来实现这一点,而且我在过去的5-6个小时里一直坚持实现这个小功能,但它就是这样。我需要帮助在用户的localStorage上存储一个最初值为1的变量。如果用户单击某个按钮,则localStorage值将更新为0。如果他再次单击,它将再次变为1。此值用于在网站的亮模式和暗模式之间切换。最初,我将css变量设置为1(用于暗模式(,并且每当用户单击按钮时,我想只使用普通的javascript(没有库(来更新它。按钮的代码在第二次尝试的代码中。或者也可以在我关于同一项目的最后一篇stackoverflow帖子中找到。

以下是我尝试实现它的几个代码:

在没有本地存储和初始变量值为0:的情况下实现并完美工作的代码

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
<style>
:root {
--numvar: 0;
}
html {
filter: invert(var(--numvar));
}

body {
background: #fff;
}
.outer-button {
display: inline-block;
height: 28px;
width: 28px;
position: relative;
margin: 0 3px;
}
.inner-button {
display: inline-block;
position: absolute;
width: 100%;
height: 100%;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4), inset 0px 0px 1px 2px white;
border-radius: 20px;
background: #f5f5f5;
}
span {
display: inline-block;
vertical-align: middle;
}
.status-text {
color: white;
text-transform: uppercase;
font-size: 11px;
font-family: Futura, sans-serif;
transition: all 0.2s ease;
}
.sliding-switch {
height: 28px;
width: 72px;
position: relative;
}
.outer-switch-box {
overflow: hidden;
height: 100%;
width: 100%;
display: inline-block;
border-radius: 20px;
position: relative;
box-shadow: inset 0 1px 3px 0px #818181, 0px 1px 2px 1px white;
transition: all 0.3s ease;
transition-delay: 65ms;
position: absolute;
z-index: 1;
}
.inner-switch-box {
position: relative;
width: 175px;
transition: all 0.3s ease;
}
/* .switch-checkbox:checked+.outer-switch-box .unchecked-text {
color: transparent;
}
.switch-checkbox:not(:checked)+.outer-switch-box .checked-text {
color: transparent;
} */
.switch-checkbox:checked+.outer-switch-box .inner-switch-box {
left: 20px;
}
.switch-checkbox:not(:checked)+.outer-switch-box .inner-switch-box {
left: -27px;
}
.switch-checkbox:checked+.outer-switch-box {
/* background-image: linear-gradient(#b6d284, #b6d284); */
background: #492d7b;
/* background: #b6d284; */
}
.switch-checkbox:not(:checked)+.outer-switch-box {
/* background-image: linear-gradient(#cbcbcb, #dbdbdb); */
background: #dbdbdb;
}
[type="checkbox"] {
margin: 0;
padding: 0;
appearance: none;
width: 100%;
height: 100%;
border: 1px solid black;
position: absolute;
top: 0;
left: 0;
z-index: 100;
opacity: 0;
}
.unchecked-text{
color: black !important;
font-weight: 700;
}
.btn-heading{
color: black;
font-family: 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Open Sans', 'Helvetica Neue', 'sans-serif';
padding: .4vw 0;
}
body{
float: left;
}
</style>
</head>
<body>

<div class="btn-heading">Change Mode</div>
<div class="sliding-switch">
<input type="checkbox" id="btn" class="switch-checkbox" />
<div class="outer-switch-box">
<div class="inner-switch-box">
<span class="status-text checked-text">on</span>
<span class="outer-button">
<span class="inner-button"></span>
</span>
<span class="status-text unchecked-text" >off</span>
</div>
</div>
</div>
<script>
document.getElementById("btn").addEventListener("click", myfunc);
function myfunc() {
let root = document.documentElement;
let elem = getComputedStyle(root).getPropertyValue("--numvar");

console.log(elem);
if (elem == 0 ) {
elem = 1;
}
else if (elem == 1 ) {
elem = 0;
}
// alert(elem);
console.log(elem);
root.style.setProperty("--numvar", elem);
}

</script>
</body>
</html>

在此之前:

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
<style>
:root {
--numvar: 0;
}
html {
filter: invert(var(--numvar));
}

body {
background: #fff;
}
.outer-button {
display: inline-block;
height: 28px;
width: 28px;
position: relative;
margin: 0 3px;
}
.inner-button {
display: inline-block;
position: absolute;
width: 100%;
height: 100%;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4), inset 0px 0px 1px 2px white;
border-radius: 20px;
background: #f5f5f5;
}
span {
display: inline-block;
vertical-align: middle;
}
.status-text {
color: white;
text-transform: uppercase;
font-size: 11px;
font-family: Futura, sans-serif;
transition: all 0.2s ease;
}
.sliding-switch {
height: 28px;
width: 72px;
position: relative;
}
.outer-switch-box {
overflow: hidden;
height: 100%;
width: 100%;
display: inline-block;
border-radius: 20px;
position: relative;
box-shadow: inset 0 1px 3px 0px #818181, 0px 1px 2px 1px white;
transition: all 0.3s ease;
transition-delay: 65ms;
position: absolute;
z-index: 1;
}
.inner-switch-box {
position: relative;
width: 175px;
transition: all 0.3s ease;
}
/* .switch-checkbox:checked+.outer-switch-box .unchecked-text {
color: transparent;
}
.switch-checkbox:not(:checked)+.outer-switch-box .checked-text {
color: transparent;
} */
.switch-checkbox:checked+.outer-switch-box .inner-switch-box {
left: 20px;
}
.switch-checkbox:not(:checked)+.outer-switch-box .inner-switch-box {
left: -27px;
}
.switch-checkbox:checked+.outer-switch-box {
/* background-image: linear-gradient(#b6d284, #b6d284); */
background: #492d7b;
/* background: #b6d284; */
}
.switch-checkbox:not(:checked)+.outer-switch-box {
/* background-image: linear-gradient(#cbcbcb, #dbdbdb); */
background: #dbdbdb;
}
[type="checkbox"] {
margin: 0;
padding: 0;
appearance: none;
width: 100%;
height: 100%;
border: 1px solid black;
position: absolute;
top: 0;
left: 0;
z-index: 100;
opacity: 0;
}
.unchecked-text{
color: black !important;
font-weight: 700;
}
.btn-heading{
color: black;
font-family: 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Open Sans', 'Helvetica Neue', 'sans-serif';
padding: .4vw 0;
}
body{
float: left;
}
</style>
</head>
<body>

<div class="btn-heading">Change Mode</div>
<div class="sliding-switch">
<input type="checkbox" id="btn" class="switch-checkbox" />
<div class="outer-switch-box">
<div class="inner-switch-box">
<span class="status-text checked-text">on</span>
<span class="outer-button">
<span class="inner-button"></span>
</span>
<span class="status-text unchecked-text" >off</span>
</div>
</div>
</div>
<script>
document.getElementById("btn").addEventListener("click", myfunc);
let avar = true; //assume it exists
if (localStorage.hardtoimplement) {
avar = true;
}
else {
localStorage.setItem("hardtoimplement", "on")
}
console.log(localStorage.getItem("hardtoimplement"));
var num = 1;
function myfunc() {
let root = document.documentElement;
let elem = getComputedStyle(root).getPropertyValue("--numvar");

if (typeof (Storage) !== "undefined") {
// console.log(num);
if (localStorage.getItem("hardtoimplement") == "on") {
num = 1;
}
else if (localStorage.getItem("hardtoimplement") == "off") {
num = 0;
}
console.log(num);
}
else {
alert("Sorry, your browser does not support web storage");
}
// console.log(num);
console.log(localStorage.getItem("hardtoimplement"));
if (localStorage.getItem("hardtoimplement") == "on") {
localStorage.hardtoimplement = "off";
}
else if (localStorage.getItem("hardtoimplement") == "off") {
localStorage.hardtoimplement = "on";
}
console.log(elem);
if (num == 0 ) {
num = 1;
}
else if (num == 1 ) {
num = 0;
}
// alert(num);
console.log(num);
root.style.setProperty("--numvar", num);
}

</script>
</body>
</html>

第一次尝试:

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
<script>
let avar = true; //assume it exists
if (localStorage.thisisvar) {
avar = true;
}
else {
localStorage.setItem("thisisvar", "on")
}
console.log(localStorage.getItem("thisisvar"));
var num = 0;
function myfunc() {
if (typeof (Storage) !== "undefined") {
// console.log(num);
if (localStorage.getItem("thisisvar") == "on") {
num = 1;
}
else if (localStorage.getItem("thisisvar") == "off") {
num = 0;
}
console.log(num);
}
else {
alert("Sorry, your browser does not support web storage");
}
// console.log(num);
console.log(localStorage.getItem("thisisvar"));
if (localStorage.getItem("thisisvar") == "on") {
localStorage.thisisvar = "off";
}
else if (localStorage.getItem("thisisvar") == "off") {
localStorage.thisisvar = "on";
}
}
function func2(){
alert(num);  //initial value is 0 here
}
</script>
</head>
<body>
<button id="result" onclick=" myfunc()">hi</button>
<button onclick="func2()">b2</button>
</body>
</html>

我试着在很多地方寻找这个功能,比如谷歌、codepen、stackoverflow等。我确实找到了很多这个功能的实现,但我无法单独将它们集成到我的项目中。

该要求基本上可以定义为:CSS变量最初设置为1,单击按钮后应更改为0。如果用户刷新了页面,它仍然应该是0

谢谢。

编辑:

答案与项目的集成:

<!DOCTYPE html>
<html lang="en">
<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>Document</title>
<style>
:root {
--numvar: 0;
}
html {
filter: invert(var(--numvar));
}

body {
background: #fff;
}
.outer-button {
display: inline-block;
height: 28px;
width: 28px;
position: relative;
margin: 0 3px;
}
.inner-button {
display: inline-block;
position: absolute;
width: 100%;
height: 100%;
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.4), inset 0px 0px 1px 2px white;
border-radius: 20px;
background: #f5f5f5;
}
span {
display: inline-block;
vertical-align: middle;
}
.status-text {
color: white;
text-transform: uppercase;
font-size: 11px;
font-family: Futura, sans-serif;
transition: all 0.2s ease;
}
.sliding-switch {
height: 28px;
width: 72px;
position: relative;
}
.outer-switch-box {
overflow: hidden;
height: 100%;
width: 100%;
display: inline-block;
border-radius: 20px;
position: relative;
box-shadow: inset 0 1px 3px 0px #818181, 0px 1px 2px 1px white;
transition: all 0.3s ease;
transition-delay: 65ms;
position: absolute;
z-index: 1;
}
.inner-switch-box {
position: relative;
width: 175px;
transition: all 0.3s ease;
}
/* .switch-checkbox:checked+.outer-switch-box .unchecked-text {
color: transparent;
}
.switch-checkbox:not(:checked)+.outer-switch-box .checked-text {
color: transparent;
} */
.switch-checkbox:checked+.outer-switch-box .inner-switch-box {
left: 20px;
}
.switch-checkbox:not(:checked)+.outer-switch-box .inner-switch-box {
left: -27px;
}
.switch-checkbox:checked+.outer-switch-box {
/* background-image: linear-gradient(#b6d284, #b6d284); */
background: #492d7b;
/* background: #b6d284; */
}
.switch-checkbox:not(:checked)+.outer-switch-box {
/* background-image: linear-gradient(#cbcbcb, #dbdbdb); */
background: #dbdbdb;
}
[type="checkbox"] {
margin: 0;
padding: 0;
appearance: none;
width: 100%;
height: 100%;
border: 1px solid black;
position: absolute;
top: 0;
left: 0;
z-index: 100;
opacity: 0;
}
.unchecked-text{
color: black !important;
font-weight: 700;
}
.btn-heading{
color: black;
font-family: 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Open Sans', 'Helvetica Neue', 'sans-serif';
padding: .4vw 0;
}
body{
float: left;
}
</style>
</head>
<body>
<div class="btn-heading">Change Mode</div>
<div class="sliding-switch">
<input type="checkbox" id="btn" class="switch-checkbox" onclick="change()" />
<div class="outer-switch-box">
<div class="inner-switch-box">
<span class="status-text checked-text">on</span>
<span class="outer-button">
<span class="inner-button"></span>
</span>
<span class="status-text unchecked-text" >off</span>
</div>
</div>
</div>
<script>
if (!localStorage.getItem('thisvarisgud4me')) {
localStorage.setItem("thisvarisgud4me", "1")
}
function change() {
if (localStorage.getItem('thisvarisgud4me') == '1') {
localStorage.setItem("thisvarisgud4me", '0')
} else {
localStorage.setItem("thisvarisgud4me", '1')
}
var num = Number(localStorage.getItem('thisvarisgud4me'));
let root = document.documentElement;
root.style.setProperty("--numvar", num);
}
var num = Number(localStorage.getItem('thisvarisgud4me'));
let root = document.documentElement;
root.style.setProperty("--numvar", num);
</script>
</body>
</html>

以下是正确的版本:

我认为你应该多学习一些js,因为有很多语法错误。

以下是一些资源:

  1. JavaScript参考
  2. 在freecodecamp.org上学习JS
  3. 在Codecademy学习JS
<!DOCTYPE html>
<html lang="en">
<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>Document</title>
<style>
:root {
--numvar: 0;
}
html {
filter: invert(var(--numvar));
}
</style>
</head>
<body>
<button id="res" onclick="change()">hi</button>
<script>
if (!localStorage.getItem('thisvarisgood')) {
localStorage.setItem("thisvarisgood", "1")
}
function change() {
if (localStorage.getItem('thisvarisgood') == '1') {
localStorage.setItem("thisvarisgood", '0')
} else {
localStorage.setItem("thisvarisgood", '1')
}
var num = Number(localStorage.getItem('thisvarisgood'));
let root = document.documentElement;
root.style.setProperty("--numvar", num);
}
var num = Number(localStorage.getItem('thisvarisgood'));
let root = document.documentElement;
root.style.setProperty("--numvar", num);
</script>
</body>
</html>

最近尝试的最大问题是将变量设置为;thisvarisgood";并用";thisvarisgud";。

一旦你纠正了这一点,你就需要纠正修改css的方式。在脚本中执行此操作是行不通的,因为脚本只运行一次。您需要在被调用的函数中设置它的样式,以更改本地存储值和页面加载。

编辑:正如你所看到的,另一个答案为你解决了这个问题。他更正了localStorage变量名,并在函数中设置了样式(第35-37行(。";页面加载";造型为40-41线。

最新更新