Change theme and store it in local storage

耗尽温柔 提交于 2021-02-08 11:23:20

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!