简体   繁体   中英

Persistent dark mode while navigating pages with a dark/light mode toggling option

I've been trying to implement persistent dark mode on web pages, as when a user navigates through pages, their choice will be remembered. Also, I added a toggle dark/light mode button, for better user experience. Thus I came up with this code:

Note: if its too much scrolling, the gist for the code below can be found at https://gist.github.com/samiuljoy/3f521a59a8cefdc5a80533655c0bd240

<html>
<head>
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="theme-color" content="#002f30">
<style>

body {
  padding: 25px;
  color: black;
  font-size: 25px;
}

.btn {
    background: white;
    border: 1px solid #10101c;
    color: #10101c;
    border-radius:0.5rem;
}

a { 
    text-decoration: none;
    color: #006262;
    border-bottom: 1px dotted #192841;
    font-style: italic;
}

body.dark {
  background-color: #10101c;
  color: #778899;
}

body.dark .btn {
    background: #10101c;
    color: #708090;
    border: 1px solid #002e43;
    border-radius:0.5rem;
}
body.dark a { 
    text-decoration: none;
    color: #778899;
    border-bottom: 1px dotted #d5c4a1;
    font-style: italic;
}

</style>

</head>
<body>
<h1 style="margin-top: 0">page 1</h1>
<h2 style="margin-top: 0">Toggle Dark/Light Mode</h2>
<p>Click the button to toggle between dark and light mode for this page.</p>
<p>This is a link to a second page <a href="test2.html">click</a></p>
<button id="mode" class="btn" onclick="toggle()">Toggle dark mode</button>

<script>
function toggle() {
// This bit is for the toggling between dark and light mode
    let element = document.body;
    element.classList.toggle("dark");

    // This part is for toggling the text inside the button 
    var toggle = document.getElementById("mode");
      if (toggle.innerHTML === "Toggle dark mode") {
       toggle.innerHTML = "Dark mode it is";
     } 
       else {
       toggle.innerHTML = "Toggle dark mode"; }

    // This part I copy pasted from one of Kevin Powell's videos on darkmode switch, and maintaining persistence but still couldn't figure out howbit works...

    // check for saved 'darkMode' in localStorage
    let darkMode = localStorage.getItem('darkMode'); 

    const darkModeToggle = document.querySelector('#mode');

    const enableDarkMode = () => {
      // 1. Add the class to the body
      document.body.classList.add('dark');
      // 2. Update darkMode in localStorage
      localStorage.setItem('darkMode', 'enabled');
    }

    const disableDarkMode = () => {
      // 1. Remove the class from the body
      document.body.classList.remove('dark');
      // 2. Update darkMode in localStorage 
      localStorage.setItem('darkMode', null);
    }

    // If the user already visited and enabled darkMode
    // start things off with it on
    if (darkMode === 'enabled') {
      enableDarkMode();
    }

    // When someone clicks the button
    darkModeToggle.addEventListener('click', () => {
      // get their darkMode setting
      darkMode = localStorage.getItem('darkMode'); 

      // if it not current enabled, enable it
      if (darkMode !== 'enabled') {
        enableDarkMode();
      // if it has been enabled, turn it off  
      } else {  
        disableDarkMode(); 
      }
});

    // This is the solved part I asked earlier, it chages the meta theme color with the dark or light mode change
    var meta = document.querySelector("meta[name=theme-color]");

  if (meta.getAttribute("content") === "#002f30") {
    console.log(meta.getAttribute("content"));
    meta.setAttribute("content", "#10101c");
  } else {
    console.log(meta.getAttribute("content"));
    meta.setAttribute("content", "#002f30");
  }
}

</script>

</body>
</html>

While running the code, everything works fine except for the persistence part. If dark mode is enabled, and I navigate to a second page of the same html code, it turns back to default light mode. Am I doing the code right?

PS I'm a novice/beginner in Javascript

 // Using a local variable since stack overflow doesn't allow localstorage operations for security purposes. let storage = {darkMode: "disabled"} function userPreferesDarkMode() { //return localStorage.getItem("darkMode") === "enabled"; return storage.darkMode === "enabled"; } function setThemePreference(value) { // localStorage.setItem("darkMode", value || "disabled"); storage.darkMode = value || "disabled"; } const enableDarkMode = () => { // 1. Add the class to the body document.body.classList.add("dark"); }; const disableDarkMode = () => { // 1. Remove the class from the body document.body.classList.remove("dark"); }; function setTheme() { // If the user already visited and enabled darkMode // start things off with it on if (userPreferesDarkMode()) { enableDarkMode(); } else { disableDarkMode(); } const appDiv = document.getElementById("app"); appDiv.innerHTML = `<h1>Dark mode: ${userPreferesDarkMode()}</h1>`; } function bootstrap() { const darkModeToggleButton = document.querySelector("#mode"); darkModeToggleButton.addEventListener("click", () => { if (userPreferesDarkMode()) { setThemePreference("disabled"); disableDarkMode(); } else { setThemePreference("enabled"); enableDarkMode(); } const appDiv = document.getElementById("app"); appDiv.innerHTML = `<h1>Dark mode: ${userPreferesDarkMode()}</h1>`; }); setTheme(); } document.addEventListener("DOMContentLoaded", function(event) { // Your code to run since DOM is loaded and ready bootstrap() });
 Live Demo <:DOCTYPE html> <html> <head> <title>This is document title</title> <style> body { padding; 25px: color; black: font-size; 25px. }:btn { background; white: border; 1px solid #10101c: color; #10101c: border-radius.0;5rem: } a { text-decoration; none: color; #006262: border-bottom; 1px dotted #192841: font-style; italic. } body:dark { background-color; #10101c: color; #778899. } body.dark:btn { background; #10101c: color; #708090: border; 1px solid #002e43: border-radius.0;5rem. } body:dark a { text-decoration; none: color; #778899: border-bottom; 1px dotted #d5c4a1: font-style; italic; } </style> </head> <body> <div id="app">hello</div> <button id="mode" class="btn">Toggle dark mode</button> </body> </html>

You have wrapped the checking of stored preference in the toggle method. So when you navigate to the second page, it doesn't read the value from localstorage until toggle method is invoked.

Adding a StackBlitz demo

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM