【问题标题】:Persistent dark mode while navigating pages with a dark/light mode toggling option使用暗/亮模式切换选项导航页面时持续暗模式
【发布时间】:2020-04-29 18:22:05
【问题描述】:

我一直在尝试在网页上实现持久的暗模式,因为当用户浏览页面时,他们的选择会被记住。此外,我添加了一个切换暗/亮模式按钮,以获得更好的用户体验。因此我想出了这个代码:

注意:如果滚动太多,下面代码的要点可以在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>

运行代码时,除了持久性部分外,一切正常。如果启用了暗模式,并且我导航到相同 html 代码的第二页,它会返回默认的亮模式。我做的代码对吗?

附注我是 Javascript 的新手/初学者

【问题讨论】:

  • 看起来应该可以了。
  • 没有。仅当单击 toggle 按钮时才会从本地存储检查模式。当页面加载时,按钮点击也会自动发生,因为它有onclick="toggle()

标签: javascript html css


【解决方案1】:

// 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>

您已经在toggle 方法中封装了对存储首选项的检查。因此,当您导航到第二页时,它不会从 localstorage 读取值,直到调用 toggle 方法。

添加StackBlitz demo

【讨论】:

  • @SamiulJoy 我添加了一个工作演示。注意我直接调用了bootstrap函数,你应该等到dom完全加载。
  • @SamiulJoy 堆栈闪电战演示拥有您需要的一切,对吧?我也添加了你的 CSS 样式。
  • 它在我的 iPhone 的 safari 浏览器中按预期工作。除非本地存储以某种方式被清除,否则这绝对可以工作。
  • 我已经使用 netlify confident-volhard-71f43f.netlify.app 部署了相同的内容。请检查它是否有效。我已经添加了 2 个页面,因此您可以来回导航。
  • @Robbie 是的。检查 netlify 链接confident-volhard-71f43f.netlify.app
猜你喜欢
  • 1970-01-01
  • 2020-10-20
  • 2021-03-05
  • 2021-09-12
  • 2022-01-10
  • 2020-08-24
  • 1970-01-01
  • 2020-11-21
  • 1970-01-01
相关资源
最近更新 更多