Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

152
Visualizações
Changing between themes with Javascript

I'm trying to make a dark/light theme toggle on my website. The SVG file switches back and forth on every click, but there's an issue with the theme not switching every click.

First two clicks - theme changes as expected.

Third and fourth clicks - SVG image still changes each click, but theme doesn't change

Fifth and sixth clicks onward - theme changes as expected, cycle repeats

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()");
}


I've included a link to the code in jsfiddle so you can see exactly what's happening. Thank you for any help/advice you can give!

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

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

This kind of error is typical when you have too much JavaScript. In this example I just control the theme with the classname of the body element. All elements in the page are children of the body element and therefore it is easy to style them accordingly.

I inserted both images, so I don't need to manipulate the DOM further and then show/hide them based on the body classname as well.

//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>

about 4 years ago · Juan Pablo Isaza Relatório

0

At the beginning theme.classList is empty

Then with each subsequent click, you get the following state changes...

  1. theme.classList becomes dark-mode
  2. theme.classList becomes dark-mode, light-mode
  3. theme.classList becomes light-mode
  4. theme.classList becomes empty

I.e. dark-mode adds or cancels dark-mode, it doesn't do anything to light-mode and vice-versa.

You could give both functions both toggles provided you toggle light-mode explicitly at the beginning. Like this...

//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>

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda