Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

141
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda