使用 Javascript 在主题之间切换

Changing between themes with Javascript

我正在尝试在我的网站上进行 dark/light 主题切换。 SVG 文件在每次点击时来回切换,但主题不会在每次点击时切换。

前两次点击 - 主题按预期更改。

第三次和第四次点击 - 每次点击 SVG 图像仍会发生变化,但主题不会发生变化

第五次和第六次点击之后 - 主题按预期更改,循环重复

HTML:

<div id="themes">
   <img id="current-theme">
</div>

CSS:

body{
  background-color: #ccc;
}

#themes {
  text-align: right;
  margin-right: 10em;
  margin-top: 2em;
  transform: scale(1.5);
  cursor: pointer;
}

.dark-mode {
  background-color: rgb(65, 65, 65);
  transition: background-color 0.5s ease;

  h1 {
    color: white;
  }

  h3 {
    color: white;
  }

  button {
    background-color: white;
    color: black;
  }
}

.light-mode {
  background-color: #ccc;
  transition: background-color 0.5s ease;

  h1 {
    color: var(--primary-color);
  }

  h3 {
    color: black;
  }

  button {
    background-color: black;
    color: white;
  }
}

Javascript:

//default theme is light
document.getElementById("current-theme").src = "images/moon.svg"

var currentTheme = document.getElementById("current-theme");
currentTheme.setAttribute("onClick", "toDarkTheme()");

var theme = document.body;

function toDarkTheme() {

  document.getElementById("current-theme").src = "images/sun.svg";
  theme.classList.toggle("dark-mode");
  //currentTheme.removeAttribute("onClick");
  currentTheme.setAttribute("onClick", "toLightTheme()");
}

function toLightTheme() {

  document.getElementById("current-theme").src = "images/moon.svg";
  theme.classList.toggle("light-mode");
  //currentTheme.removeAttribute("onClick");
  currentTheme.setAttribute("onClick", "toDarkTheme()");
}


我在 jsfiddle 中的代码中包含了一个 link,这样您就可以准确地看到发生了什么。感谢您的任何 help/advice!

https://jsfiddle.net/6op0fx7L/2/#&togetherjs=zTrev7ILNd

开头theme.classList为空

随后每次点击,您都会得到以下状态变化...

  1. theme.classList 变为暗模式
  2. theme.classList 变为暗模式,亮模式
  3. theme.classList 变为轻模式
  4. theme.classList变空

即dark-mode 添加或取消 dark-mode,它对 light-mode 没有任何作用,反之亦然。

如果您在开始时明确切换灯光模式,则可以同时切换这两个功能。像这样...

//default theme is light
document.getElementById("current-theme").src = "images/moon.svg"

var currentTheme = document.getElementById("current-theme");
currentTheme.setAttribute("onClick", "toDarkTheme()");

var theme = document.body;
theme.classList.toggle("light-mode");

function toDarkTheme() {

  document.getElementById("current-theme").src = "images/sun.svg";
  theme.classList.toggle("dark-mode");
    theme.classList.toggle("light-mode");

  //currentTheme.removeAttribute("onClick");
  currentTheme.setAttribute("onClick", "toLightTheme()");
}

function toLightTheme() {

  document.getElementById("current-theme").src = "images/moon.svg";
  theme.classList.toggle("light-mode");
    theme.classList.toggle("dark-mode");

  //currentTheme.removeAttribute("onClick");
  currentTheme.setAttribute("onClick", "toDarkTheme()");
}
body{
  background-color: #ccc;
}

#themes {
  text-align: right;
  margin-right: 10em;
  margin-top: 2em;
  transform: scale(1.5);
  cursor: pointer;
}

.dark-mode {
  background-color: rgb(65, 65, 65);
  transition: background-color 0.5s ease;

  h1 {
    color: white;
  }

  h3 {
    color: white;
  }

  button {
    background-color: white;
    color: black;
  }
}

.light-mode {
  background-color: #ccc;
  transition: background-color 0.5s ease;

  h1 {
    color: var(--primary-color);
  }

  h3 {
    color: black;
  }

  button {
    background-color: black;
    color: white;
  }
}
<div id="themes">
  <!--The icon and theme will change on click-->
  <img id="current-theme">
</div>

当你有太多的时候,这种错误是典型的JavaScript。在此示例中,我仅使用 body 元素的类名来控制主题。页面中的所有元素都是 body 元素的 children,因此很容易为它们设置相应的样式。

我插入了两个图像,所以我不需要进一步操作 DOM 然后 show/hide 它们也基于 body 类名。

//default theme is light
document.body.classList.add("light-mode");

document.getElementById("themes").addEventListener('click', e => {
  if(document.body.classList.contains("light-mode")){
    document.body.classList.replace("light-mode", "dark-mode");
  }else{
    document.body.classList.replace("dark-mode", "light-mode");
  }
});
#themes {
  float: right;
  margin-right: 10em;
  margin-top: 1em;
  transform: scale(1.5);
  cursor: pointer;
}

.dark-mode #themes img, .light-mode #themes img {
  position: absolute;
  display: none;
}

.dark-mode #themes img.sun {
  display: block;
}

.light-mode #themes img.moon {
  display: block;
}

.dark-mode {
  background-color: rgb(65, 65, 65);
  transition: background-color 0.5s ease;
}

.dark-mode h1 {
  color: white;
}

.light-mode {
  background-color: #ccc;
  transition: background-color 0.5s ease;
}

.light-mode h1 {
  color: black;
}
<div id="themes">
  <!--The icon and theme will change on click-->
  <img class="sun" src="images/sun.svg" alt="sun"/>
  <img class="moon" src="images/moon.svg" alt="moon"/>
</div>
<h1>Mode</h1>