问题
I have two themes "dark" and "light", and I want the theme to change when clicking the checkbox.
This is how I changed the theme:
document.documentElement.setAttribute('data-theme', 'dark');
And now, this is working. But I want this change to be saved in local storage, thus even after reloading the page, the theme to stay as it is without changing.
here is my code:
checkBox.addEventListener('change', function () {
if(this.checked) {
document.documentElement.setAttribute('data-theme', 'dark');
localStorage.setItem( 'data-theme', 'dark');
}
else {
document.documentElement.setAttribute('data-theme', 'light');
localStorage.setItem('data-theme', 'light');
}
})
Did I made a mistake or is there something I don't understand?
回答1:
May try it like this:
var checkBox = document.getElementById('cb');
var theme = window.localStorage.getItem('data-theme');
if(theme) document.documentElement.setAttribute('data-theme', theme);
checkBox.checked = theme == 'dark' ? true : false;
checkBox.addEventListener('change', function () {
if(this.checked){
document.documentElement.setAttribute('data-theme', 'dark');
window.localStorage.setItem('data-theme', 'dark');
} else {
document.documentElement.setAttribute('data-theme', 'light');
window.localStorage.setItem('data-theme', 'light');
}
});
<input id="cb" type="checkbox" />
<label for="cb">Checkbox</label>
回答2:
You needed some steps for about these solutions:
- get the previous set value from localStroge
- get the checkbox element
- set checkbox conditionally based on the previous local storage value if not set then default false
and finally set and unset logic
var dragTheme = window.localStorage.getItem('dark-theme'); //get the privious seted value
var themeCheckBox = document.getElementById('themeCheck'); // get the checkbox element
themeCheckBox.checked = (dragTheme == "true")? true : false; // set checkbox conditionally base on privious set value if not set then default false
function myFunction() { // triger when change value of checkbox
if(themeCheckBox.checked) {
document.documentElement.setAttribute('dark-theme', 'dark');
window.localStorage.setItem('dark-theme', true);
}else {
document.documentElement.setAttribute('dark-theme', 'light');
window.localStorage.setItem('dark-theme', false);
}
}
<label for="themeCheck">
<input type="checkbox" id="themeCheck" onchange="myFunction()" /> Drak Theme
</label>
回答3:
Alright gangster this is what we gotta do:
Add this .js file to your project:
export class ThemeManager {
'use-strict';
/**
* Constructs object of class ThemeManager
* @param {string} themeToggle - the element that changes the website theme on click
* @param {string} theme - light for initial theme light and vice versa for dark
*/
constructor(themeToggle, theme = 'light') {
//get theme toggle DOM node
if (!themeToggle) {
console.error(`A valid DOM element must be passed as the themeToggle. You passed ${themeToggle}`);
return;
}
this.themeToggle = themeToggle;
this.themeToggle.addEventListener('click', () => this.switchTheme());
//get initial theme and apply it
this.theme = theme;
if (localStorage.getItem('data-theme')) {
if (localStorage.getItem('data-theme') === (theme === 'light' ? 'dark' : 'light')) {
this.theme = (theme === 'light' ? 'dark' : 'light');
}
}
else if (window.matchMedia(`(prefers-color-scheme: ${(theme === 'light' ? 'dark' : 'light')})`).matches) {
this.theme = (theme === 'light' ? 'dark' : 'light');
}
this._applyTheme();
//add listener to change web theme on os theme change
window.matchMedia('(prefers-color-scheme: light)').addEventListener('change', (e) => {
this.theme = (e.matches ? 'light' : 'dark');
this._applyTheme();
});
}
/**
* Private _applyTheme sets documentElement and localStorage 'data-theme' attribute
* effectively changing the style of the page due to the css changing on 'data-theme'
*/
_applyTheme = () => {
this.themeToggle.innerHTML = (this.theme === 'light' ? 'Dark' : 'Light');
document.documentElement.setAttribute('data-theme', this.theme);
localStorage.setItem('data-theme', this.theme);
}
/**
* switchTheme toggles the website theme on themeToggle event: 'click'
*/
switchTheme = () => {
this.theme = (this.theme === 'light' ? 'dark' : 'light');
this._applyTheme();
}
}
Add this css to your pages .css file:
/* Dark/Light Mode Support Modifications
-------------------------------------------------- */
a, a:hover {
color: var(--link-white-color);
}
.dropdown-menu {
background: var(--bg-color);
}
.dropdown-item {
color: var(--link-white-color);
}
hr {
background-color: var(--link-white-color);
height: 1px;
border: 0;
}
/* Dark/Light Mode Support
-------------------------------------------------- */
/*Light*/
:root {
--font-color: #000;
--link-color: #1C75B9;
--link-white-color: #000;
--bg-color: rgb(243,243,243);
}
/*Dark*/
[data-theme="dark"] {
--font-color: #c1bfbd;
--link-color: #0a86da;
--link-white-color: #c1bfbd;
--bg-color: #333;
}
Now all you gotta do in your html file is this:
<html>
<head>
<title>your_title</title>
<link rel="stylesheet" href="path/to/your/css">
</head>
<body>
<button id="themeToggle"></button>
<script type="module" src="path/to/ThemeManager.js"></script>
<script type="module">
import {ThemeManager} from 'path/to/ThemeManager.js';
new ThemeManager(document.getElementById('themeToggle'));
</script>
</body>
</html>
来源:https://stackoverflow.com/questions/56871118/change-theme-and-store-it-in-local-storage