Estoy tratando de alternar un tema claro/oscuro en mi sitio web. El archivo SVG cambia de un lado a otro con cada clic, pero hay un problema con el tema que no cambia cada clic.
Primeros dos clics: el tema cambia como se esperaba.
Clics tercero y cuarto: la imagen SVG aún cambia con cada clic, pero el tema no cambia
Quinto y sexto clic en adelante: el tema cambia como se esperaba, el ciclo se repite
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()"); }He incluido un enlace al código en jsfiddle para que pueda ver exactamente lo que está sucediendo. ¡Gracias por cualquier ayuda/consejo que puedas dar!
Este tipo de error es típico cuando tienes demasiado JavaScript. En este ejemplo, solo controlo el tema con el nombre de clase del elemento del cuerpo. Todos los elementos de la página son elementos secundarios del elemento del cuerpo y, por lo tanto, es fácil diseñarlos en consecuencia.
Inserté ambas imágenes, por lo que no necesito manipular más el DOM y luego mostrarlas/ocultarlas según el nombre de clase del cuerpo también.
//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>Al principio, theme.classList está vacío.
Luego, con cada clic subsiguiente, obtendrá los siguientes cambios de estado...
Es decir, el modo oscuro agrega o cancela el modo oscuro, no le hace nada al modo claro y viceversa.
Puede dar a ambas funciones ambos conmutadores siempre que cambie el modo de luz explícitamente al principio. Como esto...
//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>