I am a working on a portfolio website that has a light/darkmode theme switch. The switch works, but it does not save the input. So when the user refreshes or clicks on a navigation link, the website goes back to the default lightmode. I want it to remember the state. I know that I have to use localStorage to make it work, but I can not seem to figure out how to do it.
Website: www.hermanvulkers.com
JavaScript theme switch code:
button.addEventListener("click", function () {
if (document.body.classList.contains("light-theme")) {
// Turn light mode off -> dark mode on
document.body.classList.toggle("light-theme");
document.getElementById('themeswitcher').innerHTML = `<span>Dark</span><img src="images/moon.png" alt="Choose website theme">`;
} else {
// Turn dark mode off -> light mode on
document.body.classList.toggle("light-theme");
document.getElementById('themeswitcher').innerHTML = `<span>Light</span><img src="images/sunrise.png" alt="Choose website theme"></img>`;
}
});
HTML button code:
<button class="themeswitcher" id="themeswitcher">
<span>Dark</span>
<img src="images/moon.png" alt="Choose website theme">
</button>
Is anyone able to help? Thanks in advance!
Your code is unnecessarily complex.
Here is a full version
window.addEventListener("load",function() {
const theme = localStorage.getItem("theme");
if (theme) document.body.classList.toggle("light-theme",theme==="light")
document.getElementById("themeswitcher").addEventListener("click", function () {
const light = document.body.classList.contains("light-theme")
this.innerHTML = `<span>${light? 'Dark' : 'light'}</span><img src="images/${light? 'moon' : 'sunrise'}.png" alt="Choose website theme">`;
document.body.classList.toggle("light-theme");
localStorage.setItem("theme",light?"dark":"light");
});
});
You can add it like this:
button.addEventListener("click", function () {
if (document.body.classList.contains("light-theme")) {
// Turn light mode off -> dark mode on
window.localStorage.setItem('darkmodeTurnedOn', 'true');
document.body.classList.toggle("light-theme");
document.getElementById('themeswitcher').innerHTML = `<span>Dark</span><img src="images/moon.png" alt="Choose website theme">`;
} else {
// Turn dark mode off -> light mode on
document.body.classList.toggle("light-theme");
window.localStorage.setItem('darkmodeTurnedOn', 'false');
document.getElementById('themeswitcher').innerHTML = `<span>Light</span><img src="images/sunrise.png" alt="Choose website theme"></img>`;
}
});
Also, on initial loading of your site, you should have listener to switch this on or off, like this:
<body onload="setTheme">
And in the setTheme function you can do the following:
function setTheme(){
if (window.localStorage.getItem('darkmodeTurnedOn') === 'true'){
document.body.classList.remove("light-theme");
}
}
You can simply set an item into the localStorage with:
localStorage.setItem('key', value);
and then access it with
let value = localStorage.getItem('key');
So I think this should work:
button.addEventListener("click", function () {
if (document.body.classList.contains("light-theme")) {
// Turn light mode off -> dark mode on
document.body.classList.toggle("light-theme");
document.getElementById('themeswitcher').innerHTML = `<span>Dark</span><img src="images/moon.png" alt="Choose website theme">`;
window.localStorage.setItem('darkMode', 'true');
} else {
// Turn dark mode off -> light mode on
document.body.classList.toggle("light-theme");
document.getElementById('themeswitcher').innerHTML = `<span>Light</span><img src="images/sunrise.png" alt="Choose website theme"></img>`;
window.localStorage.setItem('darkMode', 'false');
}
});
And somewhere in the beginning of your code:
let wasDarkMode = window.localStorage.getItem('darkMode');
if (wasDarkMode) {
document.body.classList.toggle("light-theme");
document.getElementById('themeswitcher').innerHTML = `<span>Dark</span><img src="images/moon.png" alt="Choose website theme">`;
} else {
document.body.classList.toggle("light-theme");
document.getElementById('themeswitcher').innerHTML = `<span>Light</span><img src="images/sunrise.png" alt="Choose website theme"></img>`;
}
This can be used to set and retvie the switch state. Retrieve it when you need to check the state. Instead of "if (document.body.classList.contains("light-theme"))" you should just use the localstorage state. Just set the default state to localstorage if it is null.
export const set = (key, value) => {
localStorage.setItem(key, JSON.stringify(value));
};
export const retrieve = key => {
try {
return JSON.parse(localStorage.getItem(key));
} catch (error) {
return null;
}
};
export const remove = key => localStorage.removeItem(key);
export const exists = key => localStorage.getItem(key) !== null;
Here is a theme switcher for two or more themes. Working with localstorage. Tell me if it works great and if you have questions. :)
document.addEventListener("DOMContentLoaded", function() {
var themesList = ['dark-theme', 'light-theme', 'other-theme'];
var theme = localStorage["theme"] || themesList[0] /*if localStorage["theme"] exists || default is dark-theme*/;
const updateTheme = (themeToUpdate = theme)=>{
switch (themeToUpdate) {
case 'light-theme':
document.getElementById('themeswitcher').setAttribute('data-theme', themeToUpdate); // better to use data-* attributes for javascript use only
document.getElementById('themeswitcher').innerHTML = `<span>Light</span><img src="images/sunrise.png" alt="Choose website theme">`;
break;
case 'dark-theme':
document.getElementById('themeswitcher').setAttribute('data-theme', themeToUpdate);
document.getElementById('themeswitcher').innerHTML = `<span>Dark</span><img src="images/moon.png" alt="Choose website theme">`;
break;
case 'other-theme':
document.getElementById('themeswitcher').setAttribute('data-theme', themeToUpdate);
document.getElementById('themeswitcher').innerHTML = `<span>Other</span><img src="whatever/you/want.png" alt="Choose website theme">`;
break;
default:
break;
}
}
updateTheme(theme);
button.addEventListener("click", function () {
let nextIndex = (themesList.indexOf(theme) >= themeList.length - 1) ? 0 : themesList.indexOf(theme) + 1;
theme = themesList[nextIndex];
localStorage["theme"] = theme;
updateTheme(theme);
});
});
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.