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
CodePudding user response:
At the beginning theme.classList is empty
Then with each subsequent click, you get the following state changes...
- theme.classList becomes dark-mode
- theme.classList becomes dark-mode, light-mode
- theme.classList becomes light-mode
- 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>