I had a button that change page theme to dark-mode. when you click on, it works but when refershing the page, changes will be not save. pls help me to fix that🙏🏻
html:
<div class="container">
<label for="check">change theme: </label
><input type="checkbox" name="" id="check" class="checkbox" />
</div>
jQuery:
jQuery(document).ready(function () {
jQuery('#check').change(function () {
let data = {
"night_details": "div",
"night": "body",
"tik":"checked",
}
localStorage.setItem("night-theme", JSON.stringify(data));
let theme = localStorage.getItem('night-theme');
if(this.checked) {
jQuery('body').addClass(JSON.parse(theme).night);
jQuery('.container').addClass(JSON.parse(theme).night_details);
console.log(JSON.parse(theme));
jQuery(this).attr("checked", JSON.parse(theme).tik);
}else {
localStorage.clear(theme);
jQuery('body').removeClass(JSON.parse(theme).night);
jQuery('.container').removeClass(JSON.parse(theme).night_details);
jQuery(this).removeAttr("checked");
}
if(localStorage.getItem('night-theme')) {
let theme = localStorage.getItem('night-theme');
jQuery('body').addClass(JSON.parse(theme).night);
jQuery('.container').addClass(JSON.parse(theme).night_details);
jQuery('#check').attr("checked", JSON.parse(theme).tik);
}
else {
localStorage.clear(theme);
jQuery('body').removeClass(JSON.parse(theme).night);
jQuery('.container').removeClass(JSON.parse(theme).night_details);
jQuery('#check').removeAttr("checked");
}
});
});
You save the state of the checkbox and theme when the checkbox is updated, but you don't read that back out and update the DOM when the page first loads. You just need to move your second if
statement in to document.ready
instead of within the checkbox change
handler.
Also note that the logic can be improved. Call JSON.parse()
and JSON.stringify()
once and save their values in a variable that you can re-use. Also, you don't need to explicitly set the state of the DOM if there is no theme data in localStorage as the page will already be in that state. In addition, the tik
property in the theme object is redundant, as you already know what state the checkbox will be in given if any theme data is present in localStorage.
With all that said, try this:
<div class="container">
<label for="check">change theme: </label>
<input type="checkbox" name="" id="check" class="checkbox" />
</div>
let data = {
"night_details": "div",
"night": "body"
}
jQuery($ => {
const $body = $('body');
const $container = $('.container');
const $check = $('#check');
// set theme on load
let theme = JSON.parse(localStorage.getItem('night-theme') || '{}');
if (!$.isEmptyObject(theme)) {
$body.addClass(theme.night);
$container.addClass(theme.night_details);
$check.prop("checked", true);
}
// set theme when checkbox is updated
$check.on('change', e => {
if (e.target.checked) {
localStorage.setItem("night-theme", JSON.stringify(data));
$body.addClass(data.night);
$container.addClass(data.night_details);
} else {
localStorage.clear('night-theme');
$body.removeClass(data.night);
$container.removeClass(data.night_details);
}
});
});
Here's a working example in jsFiddle, because SO snippets are sandboxed to disallow localStorage
access