HTML、CSS 和正常的 JS 代码没有给出正确的输出

HTML, CSS and normal JS Code is not giving correct output

使用 CSS 变量和 javascript 制作一个滑动按钮来切换网站主题。它工作正常,除了有一个我无法修复的小错误。如果我重新加载页面是浅色主题,则按钮的功能将被反转。按钮的“开”状​​态打开亮模式,关闭状态切换暗模式。然而,初始配置完全相反。

正如您在下面的可执行代码片段中所见,我尝试使用 click() 函数解决此问题。仅当 num 的值为 0 并重新加载页面时才会出现此问题。所以,我想如果我在localStorage中存储一个变量为false并在函数开始时检查它的值,如果它是false,那么点击按钮不执行函数,如果不是false,然后正常执行。

但由于某种原因它不起作用。请检查此代码:

if (!localStorage.getItem('thisvarisgud4me')) {
    localStorage.setItem("thisvarisgud4me", "1")
}

document.getElementById("btn").addEventListener("click", change);
var c = "true";
if (!localStorage.getItem("clickc"))
{
    localStorage.setItem("clickc", c);
}

function change() {
    if (localStorage.getItem("clickc") == "false") {
        localStorage.setItem("clickc","true");
        document.getElementById("btn").click();
    }
    else if (localStorage.getItem("clickc") == "true") {
        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);
        console.log(num);
        if (num == 0) {
            window.addEventListener("beforeunload", function (event) {
                console.log("The page is redirecting")
                alert("Reload");
                localStorage.setItem("clickc", "false");
                // document.getElementById("btn").click();
                // debugger;
            });
        }
    }
}
var num = Number(localStorage.getItem('thisvarisgud4me'));
let root = document.documentElement;
root.style.setProperty("--numvar", num);
: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: -27px;
    /*OFF*/
}

.switch-checkbox:not(:checked)+.outer-switch-box .inner-switch-box {
    left: 20px;
    /*ON*/
}

.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;
<!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>
   
<body>
    <div class="btn-heading">Dark 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" id="textp1">on</span>
                <span class="outer-button">
                    <span class="inner-button"></span>
                </span>
                <span class="status-text unchecked-text" id="textp2">off</span>
            </div>
        </div>
    </div>
</body>

</html>

您可能已经注意到,我还尝试使用 JS 操纵 CSS 伪 class 属性。但那是一团糟。然后,我想到了这种方法,我非常有信心它是正确的,但看起来我错了:(

只需添加一个条件以将“clickc”设置为“true”可能就可以解决问题。在这里,我使用了与您已经用于“thisvarisgud4me”键的条件类似的条件。

我借此机会测试了我创建的实用程序,该实用程序基本上实现了存储 API(这就是 HTML 中的 <script src="https://heretic-monkey.link/FauxStorage.js"></script>,以及为什么您所有的 localStorage 引用现在说 localStore).

因此,如果您决定将其复制并粘贴到您自己的代码中,只需搜索并将 localStore 替换为 localStorage

if (!localStore.getItem('thisvarisgud4me')) {
  localStore.setItem("thisvarisgud4me", "1")
}

document.getElementById("btn").addEventListener("click", change);
var c = "true";
if (!localStore.getItem("clickc")) {
  localStore.setItem("clickc", c);
}

function change() {
  if (localStore.getItem("clickc") == "false") {
    document.getElementById("btn").click();
    localStore.getItem("clickc") = "true";
  } else if (localStore.getItem("clickc") == "true") {
    if (localStore.getItem('thisvarisgud4me') == '1') {
      localStore.setItem("thisvarisgud4me", '0')
    } else {
      localStore.setItem("thisvarisgud4me", '1')
    }

    var num = Number(localStore.getItem('thisvarisgud4me'));
    let root = document.documentElement;
    root.style.setProperty("--numvar", num);
    console.log(num);
    if (num == 0) {
      window.addEventListener("beforeunload", function(event) {
        console.log("The page is redirecting")
        alert("Reload");
        localStore.setItem("clickc", "false");
        // document.getElementById("btn").click();
        // debugger;
      });
    }
  }
}
var num = Number(localStore.getItem('thisvarisgud4me'));
let root = document.documentElement;
root.style.setProperty("--numvar", num);
: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: -27px;
  /*OFF*/
}

.switch-checkbox:not(:checked)+.outer-switch-box .inner-switch-box {
  left: 20px;
  /*ON*/
}

.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;
}
<!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 src="https://heretic-monkey.link/FauxStorage.js"></script>
</head>
  <body>
    <div class="btn-heading">Dark 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" id="textp1">on</span>
          <span class="outer-button">
                    <span class="inner-button"></span>
          </span>
          <span class="status-text unchecked-text" id="textp2">off</span>
        </div>
      </div>
    </div>
  </body>

</html>

下面是我将如何重构它。这更像是一种面向对象的做事方式;它可能不会吸引所有人,当然也不是故意的。它对我有用,我是唯一需要让它开心的人:)。

class ThemeStore {
  _darkModeKey = "thisvarisgud4me";
  _darkMode = null;
  get darkMode() {
    if (this._darkMode === null) {
      if (!localStore.getItem(this._darkModeKey)) {
        localStore.setItem(this._darkModeKey, 0);
      }
      this._darkMode = JSON.parse(localStore.getItem(this._darkModeKey));
    }
    return this._darkMode;
  }
  set darkMode(value) {
    this._darkMode = value;
  }
  persist() {
    localStore.setItem("thisvarisgud4me", JSON.stringify(this.darkMode));
  }
}

var themeStore = new ThemeStore();
document.getElementById("btn").addEventListener("click", change);

function change(e) {
  themeStore.darkMode = e.target.checked ? 0 : 1;
  let root = document.documentElement;
  root.style.setProperty("--numvar", themeStore.darkMode);
  console.log(themeStore.darkMode);
  if (themeStore.darkMode === 0) {
    window.addEventListener("beforeunload", function(event) {
      console.log("The page is redirecting")
      themeStore.persist();
    });
  }
}

document.getElementById("btn").dispatchEvent(new CustomEvent("change"));
: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: -27px;
  /*OFF*/
}

.switch-checkbox:not(:checked)+.outer-switch-box .inner-switch-box {
  left: 20px;
  /*ON*/
}

.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;
}
<script src="https://heretic-monkey.link/FauxStorage.js"></script>
<div class="btn-heading">Dark 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" id="textp1">on</span>
      <span class="outer-button">
        <span class="inner-button"></span>
      </span>
      <span class="status-text unchecked-text" id="textp2">off</span>
    </div>
  </div>
</div>