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

t3psigkw  于 2022-11-27  发布在  Java
关注(0)|答案(2)|浏览(141)

我不敢相信我无法使用我所知道的所有资源来实现这个功能,而且我在过去的5-6个小时里一直在实现这个小功能,但事实就是这样。我需要帮助来存储一个初始值为1的用户localStorage上的单个变量。如果用户单击一个按钮,则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等等,我确实找到了这个特性的很多实现,但是我无法将它们中的任何一个集成到我自己的项目中。

The requirement can be basically defined as:
A CSS variable is initially set to 1 and it should change on button click to 0.
And if user refreshes the page, it should still be 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>
jm81lzqq

jm81lzqq1#

以下是正确的版本:
我认为你应该多学一点js,因为有很多语法错误。
以下是一些资源:

  1. JavaScript Reference
  2. Learn JS at freecodecamp.org
  3. Learn JS at Codecademy
<!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>
sqougxex

sqougxex2#

最近一次尝试的最大问题是您使用名称“thisvarisgood”设置变量,并使用“thisvarisgud”访问它。
一旦你纠正了这个错误,你就需要纠正修改css的方式。在脚本中这样做是行不通的,因为脚本只运行一次。你需要在调用函数来改变本地存储值和页面加载时设置它的样式。
edit:另一个答案为你解决了这个问题,你可以看到。2他更正了localStorage变量名,并在函数中设置了样式(第35-37行)。3“on page load”样式在第40-41行。

相关问题