Reputation: 133
This is a follow up to my previous question which can be found here How do I implement the saving of dark/light mode feature to local storage?
I want the dark/light mode to continue to retain across multiple html pages but it does not. Via local storage I am able to make a single page retain it's state after page refresh but this does not reflect in the other pages. I.e If I set index.html to dark mode, it remains on dark mode until I change the settings but if I move on to other.html, I have to manually set it to dark mode. What's the solution to this?
`
<!DOCTYPE html>
<html>
<head>
<title>index</title>
<link rel="stylesheet" href="styles.css"></link>
<script async src="script.js"></script>
</head>
<body>
<header>
<div class="controls">
<p>Light/Dark Mode</p>
<label class="toggle-switch" for="dark-mode-toggle">
<input type="checkbox" id="dark-mode-toggle" name="theme" xonclick="otherColorChanges()" onreset="restoreDefaultColor()">
<div class="toggle-switch-border">
<div class="toggle-switch-dot"></div>
</div>
</label>
</div>
</header>
<main>
<h1>Go to others.html</h1>
<a href="others.html">Click</a>
</main>
<!--Attempt to make the dark mode work on multiple pages even if it wasn't set on it-->
<script>
checkbox.addEventListener( 'click', function() {
localStorage.setItem('bodyCssProps', this.darkModeToggle.checked);
if(this.darkModeToggle.checked) {
body.classList.add('bodyCssProps')
} else {
body.classList.remove('bodyCssProps')
}
});
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>others</title>
<link rel="stylesheet" href="styles.css"></link>
<script async src="script.js"></script>
</head>
<body>
<header>
<div class="controls">
<p>Light/Dark Mode</p>
<label class="toggle-switch" for="dark-mode-toggle">
<input type="checkbox" id="dark-mode-toggle" name="theme" xonclick="otherColorChanges()" onreset="restoreDefaultColor()">
<div class="toggle-switch-border">
<div class="toggle-switch-dot"></div>
</div>
</label>
</div>
</header>
<main>
<h1>Go to others.html</h1>
<a href="others.html">Click</a>
</main>
<!--Attempt to make the dark mode work on multiple pages even if it wasn't set on it-->
<script>
checkbox.addEventListener( 'click', function() {
localStorage.setItem('bodyCssProps', this.darkModeToggle.checked);
if(this.darkModeToggle.checked) {
body.classList.add('bodyCssProps')
} else {
body.classList.remove('bodyCssProps')
}
});
</script>
</body>
</html>
<!DOCTYPE html>
<html>
<head>
<title>team</title>
<link rel="stylesheet" href="styles.css"></link>
<script async src="script.js"></script>
</head>
<body>
<header>
<div class="controls">
<p>Light/Dark Mode</p>
<label class="toggle-switch" for="dark-mode-toggle">
<input type="checkbox" id="dark-mode-toggle" name="theme" xonclick="otherColorChanges()" onreset="restoreDefaultColor()">
<div class="toggle-switch-border">
<div class="toggle-switch-dot"></div>
</div>
</label>
</div>
</header>
<main>
<h1>Go to others.html</h1>
<a href="others.html">Click</a>
</main>
<!--Attempt to make the dark mode work on multiple pages even if it wasn't set on it-->
<script>
checkbox.addEventListener( 'click', function() {
localStorage.setItem('bodyCssProps', this.darkModeToggle.checked);
if(this.darkModeToggle.checked) {
body.classList.add('bodyCssProps')
} else {
body.classList.remove('bodyCssProps')
}
});
</script>
</body>
</html>
`
`
.toggle-switch {
display : inline-flex;
align-items : center;
font-family : 'Sora', sans-serif;
font-weight : 700;
font-size : .875rem;
cursor : pointer;
}
.toggle-switch-border {
display : inline-flex;
align-items : center;
width : 60px;
height : 36px;
border : 1px solid var(--primary);
border-radius : 20px;
box-sizing : border-box;
margin-inline-start : 8px;
}
.toggle-switch input {
display: none;
}
.toggle-switch-dot {
width : 28px;
height : 28px;
border-radius : 50%;
background : var(--primary);
transform : translate3d(3px, 0, 0);
transition : transform .1s ease-in-out;
}
.toggle-switch input:checked + * .toggle-switch-dot {
transform : translate3d(26px, 0, 0);
}
body {
color : var(--primary);
font-family : "Work Sans", sans-serif;
background : var(--background);
/*box-sizing : border-box;*/
transition : color 0.5s;
transition : background 0.5s;
--dark-background : #253a52;
--dark-primary : white; /*#FFFFE3*/
--dark-link : #A9FE75;
--light-background : white; /*#ffffe3*/
--light-primary : #253a52;
--light-link : #1348da;
--background : var(--light-background);
--primary : var(--light-primary);
--link : var(--light-link);
}
a {
color : var(--link);
}
/* separator bars */
nav,
section {
border-block-end : 1px solid var(--primary);
}
/* container for dark-mode toggle */
header .controls {
display : flex;
justify-content : end;
padding : 1rem 0;
margin-right : 3rem;
}
a.btn {
display : inline-flex;
align-items : center;
background : var(--link);
color : var(--background);
text-decoration : none;
padding : 0 1rem;
height : 2.5rem;
border-radius : 1.25rem;
font-family : "Montserrat", sans-serif;
font-weight : 700;
font-size : 0.875rem;
}
`
`
/*Light/Dark mode toggle*/
class CssPropControl {
constructor(element) {
this.element = element
}
get(varName) {
return getComputedStyle(this.element).getPropertyValue(varName)
}
set(varName, val) {
return this.element.style.setProperty(varName, val)
}
}
const bodyCssProps = new CssPropControl(document.body)
let toggle = document.querySelector('#dark-mode-toggle')
toggle.addEventListener('click', updateMode);
function updateMode() {
let mode = toggle.checked ? 'dark' : 'light'
bodyCssProps.set('--background', bodyCssProps.get(`--${mode}-background`))
bodyCssProps.set('--primary', bodyCssProps.get(`--${mode}-primary`))
bodyCssProps.set('--link', bodyCssProps.get(`--${mode}-link`))
}
/*Save dark mode in local storage*/
const darkModeToggle = document.getElementById('dark-mode-toggle');
darkModeToggle.addEventListener('click', () => {
darkModeToggle.checked ? document.body.classList.add("bodyCssProps"):document.body.classList.remove("bodyCssProps");
localStorage.setItem('darkModeStatus', darkModeToggle.checked);
});
window.addEventListener('load', (event) => {
if (localStorage.getItem('darkModeStatus')=="true"){
document.body.classList.add("bodyCssProps");
document.getElementById('dark-mode-toggle').checked = true;
document.body.classList.add("bodyCssProps");
console.log('dark mode', document.body.className);
}
else {
console.log('light mode', document.body.className);
}
updateMode();
});
`
Upvotes: 2
Views: 642
Reputation: 1
I'm sorry for my English
I noticed that, on some lines, it ends up repeating the assignment of the checkbox ID to variables, and also ends up repeating the declaration of the event 'onclick' to the checkbox. Unifying them in only one event/variable can greatly optimize your code.
/*Light/Dark mode toggle*/
class CssPropControl {
constructor(element) {
this.element = element
}
get(varName) {
return getComputedStyle(this.element).getPropertyValue(varName)
}
set(varName, val) {
return this.element.style.setProperty(varName, val)
}
}
const bodyCssProps = new CssPropControl(document.body)
let toggle = document.querySelector('#dark-mode-toggle');
toggle.addEventListener('click',() =>{
let mode = toggle.checked;
updateMode(mode == true ? 'dark' : 'light');
addBodyClassProps(mode == true ? 'add' : 'remove');
setStorageMode(mode);
});
function updateMode(mode) {
bodyCssProps.set('--background', bodyCssProps.get(`--${mode}-background`))
bodyCssProps.set('--primary', bodyCssProps.get(`--${mode}-primary`))
bodyCssProps.set('--link', bodyCssProps.get(`--${mode}-link`))
}
function addBodyClassProps(act) {
if(act == 'add') {
document.body.classList.add('bodyCssProps');
console.log('dark mode', document.body.className);
} else {
document.body.classList.remove('bodyCssProps');
console.log('light mode', document.body.className);
}
}
/*Save dark mode in local storage*/
function setStorageMode(_MODE) {
localStorage.setItem('darkModeStatus', _MODE);
}
function getStorageMode() {
let storageMode = localStorage.getItem('darkModeStatus') ?? null;
if(storageMode == 'true') {
toggle.checked = true;
addBodyClassProps('add');
updateMode('dark');
}
}
window.addEventListener('load',getStorageMode());
.toggle-switch {
display : inline-flex;
align-items : center;
font-family : 'Sora', sans-serif;
font-weight : 700;
font-size : .875rem;
cursor : pointer;
}
.toggle-switch-border {
display : inline-flex;
align-items : center;
width : 60px;
height : 36px;
border : 1px solid var(--primary);
border-radius : 20px;
box-sizing : border-box;
margin-inline-start : 8px;
}
.toggle-switch input {
display: none;
}
.toggle-switch-dot {
width : 28px;
height : 28px;
border-radius : 50%;
background : var(--primary);
transform : translate3d(3px, 0, 0);
transition : transform .1s ease-in-out;
}
.toggle-switch input:checked + * .toggle-switch-dot {
transform : translate3d(26px, 0, 0);
}
body {
color : var(--primary);
font-family : "Work Sans", sans-serif;
background : var(--background);
/*box-sizing : border-box;*/
transition : color 0.5s;
transition : background 0.5s;
--dark-background : #253a52;
--dark-primary : white; /*#FFFFE3*/
--dark-link : #A9FE75;
--light-background : white; /*#ffffe3*/
--light-primary : #253a52;
--light-link : #1348da;
--background : var(--light-background);
--primary : var(--light-primary);
--link : var(--light-link);
}
a {
color : var(--link);
}
/* separator bars */
nav,
section {
border-block-end : 1px solid var(--primary);
}
/* container for dark-mode toggle */
header .controls {
display : flex;
justify-content : end;
padding : 1rem 0;
margin-right : 3rem;
}
a.btn {
display : inline-flex;
align-items : center;
background : var(--link);
color : var(--background);
text-decoration : none;
padding : 0 1rem;
height : 2.5rem;
border-radius : 1.25rem;
font-family : "Montserrat", sans-serif;
font-weight : 700;
font-size : 0.875rem;
}
<!DOCTYPE html>
<html>
<head>
<title>index</title>
<link rel="stylesheet" href="styles.css"></link>
<script async src="script.js"></script>
</head>
<body>
<header>
<div class="controls">
<p>Light/Dark Mode</p>
<label class="toggle-switch" for="dark-mode-toggle">
<input type="checkbox" id="dark-mode-toggle" name="theme" xonclick="otherColorChanges()" onreset="restoreDefaultColor()">
<div class="toggle-switch-border">
<div class="toggle-switch-dot"></div>
</div>
</label>
</div>
</header>
<main>
<h1>Go to others.html</h1>
<a href="others.html">Click</a>
</main>
</body>
</html>
Upvotes: 0
Reputation: 497
What you're wanting to do is listen to load
of the page and then retrieve the value/set the color mode. You could add some css/other logic to make it less of a flash from light to dark mode when you navigate but this will get the color mode to persist from page to page.
const isDarkMode = () => {
return localStorage.getItem('darkModeStatus', false);
}
window.addEventListener('load', () => {
if (isDarkMode()) {
darkModeToggle.checked = true;
updateMode()
}
})
Upvotes: 1
Reputation: 4435
You can accomplish this with a cookie.
document.cookie = "theme=dark; path=/; expires=Fri, 31 Dec 9999 23:59:59 GMT;"
This sets the cookie to apply to any page on the root domain with almost no expiration date.
Upvotes: 2