0

I'd like to add localstorage for dark-mode to remember the user's choice. I've read and looked at the courses and tried different ways but the code still doesn't work properly and I don't understand it. Thank you very much for your help and best regards! :)

jQuery

$(document).ready(function () {
  localStorage.getItem("theme")

    function isDark() {
        return $("html").attr("theme") == 'dark';
    }

    function darkModeToggle() {
        if (isDark()) {
            $("html").attr("theme", "light");
        }
        else {
            $("html").attr("theme", "dark");
        }
    }

    function onClickDark() {
        $('.theme-switcher').on('click', function () {
            darkModeToggle();
            if (isDark()) {
                $(this).addClass('active');
                localStorage.setItem("mode", "dark");    
            }
            else {
                $(this).removeClass('active');
                localStorage.setItem("mode", "light");
            }
        });
    }

    onClickDark();
});

HTML

<label class="theme-switcher">
            <span class="theme-switcher-label"> icons with sun and moon </span>
            <span class="theme-switcher-handle"></span>
</label>
ZiP 10
  • 3
  • 1
  • 1
    You setting item name as `mode` in localStorage. But in the 1st line, you getting that as `theme`. BTW, you were not assign that in a variable in given code – Prakash M May 03 '21 at 10:46
  • @PrakashM I also agree with you in 1st online he getting that as `theme` and also inside `function darkModeToggle()`. but in `function onClickDark()` he getting that as `mode` it might be the problem here. – Kevin M. Mansour May 03 '21 at 11:19
  • Notice also in Google Chrome you might see error say `Uncaught SecurityError: Failed to read the 'localStorage' property from 'Window': Access is denied for this document.` and you can solve the error here https://stackoverflow.com/q/30481516/14945696 – Kevin M. Mansour May 03 '21 at 11:21
  • Did my answer help you? – Kevin M. Mansour May 04 '21 at 19:41
  • Hi! indeed there is "theme" and "mode". My mistake. @KevinM.Mansour Today I will try to do it based on your code. Thanks for Your help! :) – ZiP 10 May 05 '21 at 06:10
  • @ZiP10 If my answer helped you must click grey check mark next to my answer; if my answer did not work and you found solution you must post your solution and also you must click grey check mark next to your answer. To help new people in Stack Overflow. Thanks – Kevin M. Mansour May 05 '21 at 12:25

1 Answers1

0

I will show you below sample code to show how to do Dark Mode with Local Storage in jQuery like what you want.

It will just give you idea on how that works but you can remove my style and button and create your own with your own idea with more features.

Also I see that is most professional code for Dark Mode.

This code it just toggle button which click on it to convert to dark mode, click again which will convert to Light Mode ans save that in Local Storage. And check on startup for which method user choose.

// Get the theme toggle input
const themeToggle = document.querySelector(
  '.theme-switch input[type="checkbox"]'
);
// Function that will switch the theme based on the if the theme toggle is checked or not
function switchTheme(e) {
  if (e.target.checked) {
    document.documentElement.setAttribute("data-theme", "dark");
  } else {
    document.documentElement.setAttribute("data-theme", "light");
  }
}
// Add an event listener to the theme toggle, which will switch the theme
themeToggle.addEventListener("change", switchTheme, false);
function switchTheme(e) {
  if (e.target.checked) {
    document.documentElement.setAttribute("data-theme", "dark");
    
    // Set the user's theme preference to dark
    localStorage.setItem("theme", "dark");
  } else {
    document.documentElement.setAttribute("data-theme", "light");
    
    // Set the user's theme preference to light
    localStorage.setItem("theme", "light");
  }
}
// Get the current theme from local storage
const currentTheme = localStorage.getItem("theme");
// If the current local storage item can be found
if (currentTheme) {
  // Set the body data-theme attribute to match the local storage item
  document.documentElement.setAttribute("data-theme", currentTheme);
// If the current theme is dark, check the theme toggle
  if (currentTheme === "dark") {
    themeToggle.checked = true;
  }
}
:root {
  --bg-color: #fec150;
  --font-color: #222;
  --title-color: #0067e6;
  --title-background: #fff;
  --main-border: 1px solid rgba(255, 255, 255, 0.4);
  --main-bg: rgba(255, 255, 255, 0.4);
}
[data-theme="dark"] {
  --bg-color: #111;
  --font-color: #efefef;
  --title-color: #fec150;
  --title-background: #222;
  --main-border: 1px solid rgba(255, 255, 255, 0.2);
  --main-bg: rgba(25, 25, 25, 0.4);
}
body {
  color: var(--font-color);
  background-color: var(--bg-color);
/* OTHER STYLING */
  ...
}
main {
  border: var(--main-border);
  background: var(--main-bg);
/* OTHER STYLING */
  ...
}
h1 {
  color: var(--title-color);
/* OTHER STYLING */
  ...
}
.theme-switch-wrapper {
  display: flex;
  align-items: center;
}
.theme-switch-wrapper em {
  margin-left: 10px;
  font-size: 1rem;
}
.theme-switch {
  display: inline-block;
  height: 34px;
  position: relative;
  width: 60px;
}
.theme-switch input {
  display: none;
}
.slider {
  background-color: #ccc;
  bottom: 0;
  cursor: pointer;
  left: 0;
  position: absolute;
  right: 0;
  top: 0;
  transition: 0.4s;
  border-radius: 34px;
}
.slider:before {
  background-color: #fff;
  bottom: 4px;
  content: "";
  height: 26px;
  left: 4px;
  position: absolute;
  transition: 0.4s;
  width: 26px;
  border-radius: 50%;
}
input:checked + .slider {
  background-color: #fec150;
}
input:checked + .slider:before {
  transform: translateX(26px);
}
.slider svg {
  color: #222;
  position: absolute;
  transition: opacity 0.2s ease 0s, transform 0.35s ease 0s;
  pointer-events: none;
}
.feather-moon {
  opacity: 0;
  left: 9px;
  bottom: 9px;
  transform: translateX(4px);
}
.feather-sun {
  opacity: 1;
  right: 10px;
  bottom: 9px;
  transform: translateX(0px);
}
input:checked + .slider .feather-moon {
  opacity: 1;
  transform: translateX(0);
}
input:checked + .slider .feather-sun {
  opacity: 0;
  transform: translateX(-4px);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="theme-switch-wrapper">
  <label class="theme-switch" for="checkbox">
    <input type="checkbox" id="checkbox" />
    <div class="slider">
      <svgOfSun />
      <svgOfMoon />
    </div>
  </label>
</div>

Notice : you might see error in console that say "Uncaught SecurityError: Failed to read the 'localStorage' property from 'Window': Access is denied for this document."

Solution for that error is here with full methods for Google Chrome.

Thanks for this article which I find code from (https://blog.prototypr.io/create-your-own-dark-mode-using-js-css-variables-and-localstorage-8b461864644b).

Kevin M. Mansour
  • 2,915
  • 6
  • 18
  • 35